/******************* tcpServer.c *********************/
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/tcp.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#define PORT 3000
#define BUFSIZE 1024
int tcp_state(int tcp_fd)
{
struct tcp_info info;
int optlen = sizeof(struct tcp_info);
if (getsockopt (tcp_fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&optlen) < 0) {
printf ("getsockopt() TCP_INFO error\n"); exit (0);
}
printf ("%d\n",info.tcpi_state);
if (info.tcpi_state == TCP_ESTABLISHED) return 0; /* ESTABLISHED */
else return -1;
}
int main (int argc, char **argv)
{
int listen_fd;
if ((listen_fd = socket (PF_INET, SOCK_STREAM, 0)) < 0) { printf ("socket() error\n"); exit (0); }
struct sockaddr_in acceptAddr; bzero(&acceptAddr, sizeof(acceptAddr));
acceptAddr.sin_family = PF_INET;
acceptAddr.sin_addr.s_addr = htonl (INADDR_ANY);
acceptAddr.sin_port = htons (PORT);
if (bind(listen_fd, (struct sockaddr *)&acceptAddr, sizeof(acceptAddr)) != 0) { printf("bind() error\n"); exit(0); }
if (listen (listen_fd, 1) != 0) { printf("listen() error\n"); exit(0); }
signal(SIGPIPE, SIG_IGN);
while (1) {
struct sockaddr_in clientAddr; bzero(&clientAddr, sizeof(clientAddr));
int clientSockfd, len;
len = sizeof (clientAddr);
clientSockfd = accept (listen_fd, (struct sockaddr *)&clientAddr, (socklen_t *)&len); /* accept() creates a new connected socket file descriptor. */
/* setup clientSockfd */
if (fcntl(clientSockfd, F_SETFL, O_NONBLOCK) != 0) { printf ("error: fcntl(). exit\n"); exit (0); } /* set clientSockfd nonblocking */
int keepAlive = 1;
if (setsockopt (clientSockfd,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == -1) { printf("setsockopt SO_KEEPALIVE error!\n"); exit(0); }
int keepIdle = 1; /* The time (in seconds) the connection needs to remain idle before TCP starts sending keepalive probes. */
if (setsockopt (clientSockfd,SOL_TCP,TCP_KEEPIDLE,(void *)&keepIdle,sizeof(keepIdle)) == -1) { printf("setsockopt TCP_KEEPIDLE error!\n"); exit(0); }
int keepInterval = 1; /* The time (in seconds) between individual keepalive probes. */
if (setsockopt (clientSockfd,SOL_TCP,TCP_KEEPINTVL,(void *)&keepInterval,sizeof(keepInterval)) == -1) { printf("setsockopt TCP_KEEPINTVL error!\n"); exit(0); }
int keepCount = 2; /* The maximum number of keepalive probes TCP should send before dropping the connection. */
if (setsockopt (clientSockfd,SOL_TCP,TCP_KEEPCNT,(void *)&keepCount,sizeof(keepCount)) == -1) { printf("setsockopt TCP_KEEPCNT error!\n"); exit(0); }
/* setup clientSockfd end */
char buf[BUFSIZE+1]; bzero (buf, BUFSIZE+1);
sleep(5);
if ((len = read (clientSockfd, buf, BUFSIZE)) <= 0) {
if((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading. */
} else { }
shutdown(clientSockfd, SHUT_RDWR); close (clientSockfd); /* close file descriptor */
continue;
}
printf ("read data from client %s:\n%s\n", inet_ntoa(clientAddr.sin_addr), buf);
int i;
for (i = 0; i < len; i++) {
printf ("%2.2x ", buf[i]);
if((i+1)%16 == 0) { printf ("\n"); }
}
printf ("\n");
sleep(5);
char *data = "123 456\n";
if (write (clientSockfd, data, strlen(data)) == -1) {
if((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* Non-blocking I/O has been selected using O_NONBLOCK and the write would block. */
} else { }
shutdown(clientSockfd, SHUT_RDWR); close (clientSockfd); /* close file descriptor */
continue;
}
printf ("send data to client %s:\n%s\n", inet_ntoa(clientAddr.sin_addr), data);
while (1) {
if (tcp_state (clientSockfd) != 0) break;
sleep (1);
}
shutdown(clientSockfd, SHUT_RDWR); close (clientSockfd); /* close file descriptor */
}
return 0;
}
/* convert address from presentation format to network format: inet_pton(PF_INET, "127.0.0.1", &(sa.sin_addr)); */
/*************** end of tcpServer.c ******************/ |