ioPAC RTU Controllers
C/C++ Sample Code Programming Guide
Macros | Functions
server_tcp_echo.c File Reference

Server TCP Echo More...

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <pthread.h>

Macros

#define BUFFER_SIZE   32
 

Functions

void connectionThread (void *parameter)
 
int main (int argc, char *argv[])
 

Detailed Description

Server TCP Echo

Date
04-10-2013
Author
Eddy Kao
Version
V1.0
client_server.jpg
Server TCP Echo
Introduction:
The Server will echo each byte that is sent by the Client.
Example:
1. Using default: ./server_tcp_echo
2. Setting port: ./server_tcp_echo -p1234
Default:
Port = 2323
Help:
root@Moxa:/tmp#./server_tcp_echo -h
Echo Server, server program.

Usage: ./server_tcp_echo [OPTIONS]

Options:
        -p       Port [0-65535]. Default port = 2323

Macro Definition Documentation

#define BUFFER_SIZE   32

Function Documentation

void connectionThread ( void *  parameter)
int main ( int  argc,
char *  argv[] 
)
/*******************************************************************************
* Copyright Moxa Inc.
*
* Echo Server(server)
*
* Date Author Comment
* 04-10-2013 Eddy Kao Created.
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include<sys/time.h>
#include<sys/types.h>
#include <pthread.h>
#define BUFFER_SIZE 32
void connectionThread(void *parameter)
{
int newfd = (int)parameter;
int idleTimeout = 30; //30 seconds
int exitFlag = 0;
int nBytes = 0;
char buf[BUFFER_SIZE];
fd_set fdread;
fd_set fdwrite;
struct timeval timeout;
FD_ZERO(&fdread);
FD_SET(newfd, &fdread);
FD_ZERO(&fdwrite);
FD_SET(newfd, &fdwrite);
while(1)
{
timeout.tv_sec = idleTimeout;
timeout.tv_usec = 0;
switch(select(newfd + 1, &fdread, NULL, NULL, &timeout))
{
case -1:
printf("Server: connection[%d] closed.\r\n", newfd);
exitFlag = 1;
close(newfd);
break;
case 0:
printf("Server: connection[%d] timeout, closed.\r\n", newfd);
exitFlag = 1;
close(newfd);
break;
default:
if(FD_ISSET(newfd, &fdread))
{
timeout.tv_sec = idleTimeout;
timeout.tv_usec = 0;
//Receive
memset(buf, 0, sizeof(buf));
nBytes = read(newfd, buf, sizeof(buf));
if(nBytes == -1 || nBytes == 0)
{
printf("Server: connection[%d] closed.\r\n", newfd);
exitFlag = 1;
close(newfd);
break;
}
printf("Server: connection[%d] reads %d bytes.\r\n", newfd, nBytes);
timeout.tv_sec = idleTimeout;
timeout.tv_usec = 0;
if(select(newfd + 1, NULL, &fdwrite, NULL, &timeout) > 0)
{
if(FD_ISSET(newfd, &fdwrite))
{
//Send
nBytes = write(newfd, buf, nBytes);
if(nBytes == -1 || nBytes == 0)
{
printf("Server: connection[%d] closed.\r\n", newfd);
exitFlag = 1;
close(newfd);
break;
}
}
}
printf("Server: connection[%d] writes %d bytes.\r\n", newfd, nBytes);
}
break;
}
if(exitFlag == 1) break;
}
}
int main(int argc, char* argv[])
{
int rc = 0;
int sinSize = 0;
int sockfd = 0;
int newfd = 0;
int backlog = 10;
unsigned short port = 2323; //Default port
int reuseaddr = 1;
socklen_t reuseaddr_len = sizeof(reuseaddr);
pthread_t thread;
struct sockaddr_in sockAddress;
struct sockaddr_in clientAddress;
while((rc = getopt(argc, argv, "hp:")) != -1)
{
switch(rc)
{
case 'p':
port = atoi(optarg);
break;
case '?':
case 'h':
default:
printf("Echo Server, server program.\n\n");
printf("Usage: ./server_tcp_echo [OPTIONS]\n\n");
printf("Options:\n");
printf("\t%-8s Port [%d-%d]. Default port = %d\n", "-p", 0, 65535, port);
printf("\n");
return 0;
}
}
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) //TCP connection
{
perror("socket");
exit(1);
}
sockAddress.sin_family = AF_INET;
sockAddress.sin_port = htons(port);
sockAddress.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&(sockAddress.sin_zero), 8);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, reuseaddr_len);
if(bind(sockfd, (struct sockaddr*)&sockAddress, sizeof(struct sockaddr)) == -1)
{
close(sockfd);
perror("bind");
exit(1);
}
if(listen(sockfd, backlog) == -1)
{
close(sockfd);
perror("listen");
exit(1);
}
sinSize = sizeof(struct sockaddr_in);
printf("Server: started at port:%d.\r\n", port);
while(1)
{
if((newfd = accept(sockfd, (struct sockaddr*)&clientAddress, &sinSize)) == -1)
{
close(sockfd);
perror("accept");
exit(1);
}
rc = pthread_create(&thread, NULL, (void *)connectionThread, (void *)newfd);
if(rc != 0)
{
close(newfd);
continue;
}
else
{
pthread_detach(thread);
printf("Server: connection[%d] established.\r\n", newfd);
}
}
close(sockfd);
return 0;
}