#include /* standard C i/o facilities */ #include /* Unix System Calls */ #include /* system data type definitions */ #include /* socket specific definitions */ #include /* INET constants and stuff */ #include /* IP address conversion stuff */ #include /* need for timeval struct */ /* Simple TCP chat server - accepts 2 connections and forward stuff from one socket to the other Example of using select() */ int MAXLEN=100; #define MAX(x,y) (x>y?x:y) int talk(int sd1, int sd2 ) { fd_set rdset; int rval,n; struct timeval timeout = {1,0}; char buf[MAXLEN]; while (1) { FD_ZERO(&rdset); /* Clear out everything */ FD_SET(sd1,&rdset); /* Add sd1 to the set */ FD_SET(sd2,&rdset); /* Add sd2 to the set */ /* look for input from either client, but don't wait more than 1 second */ timeout.tv_sec=1; timeout.tv_usec=0; /* call select, waiting no more than 1 second before returning */ if ((rval = select( MAX(sd1,sd2)+1, &rdset, NULL, NULL, &timeout))<0) { printf("Error calling select\n"); exit(1); } if (rval==0) { /* if select returns 0 it means the maximum time forced it to return (there is nothing available for reading) */ printf("THE CLOCK IS TICKING!\n"); } else { /* Check for input from client 1 */ if (FD_ISSET(sd1,&rdset) ) { /* There is data from client 1 (sd1) - read it */ if ((n=read(sd1,buf,MAXLEN))<0) { printf("ERROR READING\n"); exit(1); } /* If client 1 closed the connection, shut everything down */ if (n==0) { printf("DONE\n"); close(sd1); close(sd2); return(1); } /* forward the stuff to client 2 */ if (write(sd2,buf,n)<0) { printf("ERROR WRITING\n"); exit(1); } } /* Check to see if client 2 sent anything */ if (FD_ISSET(sd2,&rdset) ) { /* There is data from client 1 (sd1) - read it */ if ((n=read(sd2,buf,MAXLEN))<0) { printf("ERROR READING\n"); exit(1); } /* If client 1 closed the connection, shut everything down */ if (n==0) { printf("DONE\n"); close(sd1); close(sd2); return(1); } /* forward the stuff to client 2 */ if (write(sd1,buf,n)<0) { printf("ERROR WRITING\n"); exit(1); } } } } } int main() { int ld,sd1,sd2; struct sockaddr_in skaddr; struct sockaddr_in from; int addrlen,length; /* create a socket IP protocol family (PF_INET) TCP protocol (SOCK_STREAM) */ if ((ld = socket( PF_INET, SOCK_STREAM, 0 )) < 0) { perror("Problem creating socket\n"); exit(1); } /* establish our address address family is AF_INET our IP address is INADDR_ANY (any of our IP addresses) the port number is assigned by the kernel */ skaddr.sin_family = AF_INET; skaddr.sin_addr.s_addr = htonl(INADDR_ANY); skaddr.sin_port = htons(0); if (bind(ld, (struct sockaddr *) &skaddr, sizeof(skaddr))<0) { perror("Problem binding\n"); exit(0); } /* find out what port we were assigned and print it out */ length = sizeof( skaddr ); if (getsockname(ld, (struct sockaddr *) &skaddr, &length)<0) { perror("Error getsockname\n"); exit(1); } printf("The Server passive socket port number is %d\n",ntohs(skaddr.sin_port)); /* put the socket into passive mode (waiting for connections) */ if (listen(ld,5) < 0 ) { perror("Error calling listen\n"); exit(1); } /* now process incoming connections forever ... */ while (1) { printf("Ready for a connection...\n"); addrlen=sizeof(skaddr); if ( (sd1 = accept( ld, (struct sockaddr*) &from, &addrlen)) < 0) { perror("Problem with accept call\n"); exit(1); } printf("Got connection #1 - waiting...\n"); if ( (sd2 = accept( ld, (struct sockaddr*) &from, &addrlen)) < 0) { perror("Problem with accept call\n"); exit(1); } printf("Got 2 connections ...\n"); talk(sd1,sd2); } }