/* * multiplexed_echo_server.c -- modified from APUE book (tcp select echo server) */ #include #include #include #include #include #include #include #include #include "socket.h" #define PORT 2345 // default port int main(int argc, char *argv[]) { int i, n, imax, fdmax, csock, conn, sock; int nready, client[FD_SETSIZE]; fd_set master, cset; char buf[256]; sock = get_ssock(PORT, "tcp"); // get a server TCP socket at PORT fdmax = sock; imax = -1; for ( i = 0; i < FD_SETSIZE; i++ ) { client[i] = -1; } FD_ZERO(&master); FD_ZERO(&cset); FD_SET(sock, &master); for(;;) { cset = master; nready = select(fdmax+1, &cset, NULL, NULL, NULL); if ( FD_ISSET(sock, &cset) ) { // we have a new client connection struct sockaddr_in caddr; socklen_t clen = sizeof(caddr); conn = accept(sock, (struct sockaddr *) &caddr, &clen); for ( i = 0; i < FD_SETSIZE; i++ ) { // find a free slot if ( client[i] < 0 ) { client[i] = conn; // save descriptor break; } } if ( i == FD_SETSIZE ) { // no slot found fprintf(stderr, "Too many connections. quitting...\n"); exit(EXIT_FAILURE); } FD_SET(conn, &master); if ( fdmax < conn ) { fdmax = conn; } if ( imax < i ) { imax = i; } if ( --nready <= 0 ) { // nothing ready left for reading continue ; // the for loop } } for ( i = 0; i <= imax; i++ ) { // only client connections left for processing if ( (csock = client[i]) < 0 ) { continue; } if ( FD_ISSET(csock, &cset) ) { if ( (n = recv(csock, buf, sizeof(buf), 0)) <= 0 ) { close(csock); FD_CLR(csock, &master); client[i] = -1; } else { write(csock, buf, n); } if ( --nready == 0 ) { break; } } } } }