/***************************************************************************** *** Demo program explaining the client-server model *** *** This is the server program *** *** Written by Abhijit Das, CSE, IIT Kharagpur *** *** Last modified: October 13, 2006 *** *****************************************************************************/ #include #include #include #include #include #include #include #include /* Global constants */ #define SERVICE_PORT 41041 #define Q_SIZE 5 #define MAX_LEN 1024 /* Function prototypes */ int startServer ( ); void clientTalk ( int ); void serverLoop ( int ); int wordCount ( char * ); /* Start the server: socket(), bind() and listen() */ int startServer () { int sfd; /* for listening to port PORT_NUMBER */ struct sockaddr_in saddr; /* address of server */ int status; /* Request for a socket descriptor */ sfd = socket(AF_INET, SOCK_STREAM, 0); if (sfd == -1) { fprintf(stderr, "*** Server error: unable to get socket descriptor\n"); exit(1); } /* Set the fields of server's internet address structure */ saddr.sin_family = AF_INET; /* Default value for most applications */ saddr.sin_port = htons(SERVICE_PORT); /* Service port in network byte order */ saddr.sin_addr.s_addr = INADDR_ANY; /* Server's local address: 0.0.0.0 (htons not necessary) */ bzero(&(saddr.sin_zero),8); /* zero the rest of the structure */ /* Bind the socket to SERVICE_PORT for listening */ status = bind(sfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr)); if (status == -1) { fprintf(stderr, "*** Server error: unable to bind to port %d\n", SERVICE_PORT); exit(2); } /* Now listen to the service port */ status = listen(sfd,Q_SIZE); if (status == -1) { fprintf(stderr, "*** Server error: unable to listen\n"); exit(3); } fprintf(stderr, "+++ Server successfully started, listening to port %hd\n", SERVICE_PORT); return sfd; } /* Accept connections from clients, spawn a child process for each request */ void serverLoop ( int sfd ) { int cfd; /* for communication with clients */ struct sockaddr_in caddr; /* address of client */ int size; while (1) { /* accept connection from clients */ cfd = accept(sfd, (struct sockaddr *)&caddr, &size); if (cfd == -1) { fprintf(stderr, "*** Server error: unable to accept request\n"); continue; } fprintf(stderr, "+++ Connected with %s\n", inet_ntoa(caddr.sin_addr)); /* fork a child to process request from client */ if (!fork()) { clientTalk(cfd); fprintf(stderr, "+++ Closed connection with %s\n", inet_ntoa(caddr.sin_addr)); close(cfd); exit(0); } /* parent (server) does not talk with clients */ close(cfd); /* parent waits for termination of child processes */ while (waitpid(-1,NULL,WNOHANG) > 0); } } /* Interaction of the child process with the client */ void clientTalk ( int cfd ) { int status; int nbytes; int wc; char buffer[MAX_LEN]; /* Send greetings to client */ status = send(cfd, "!!! Welcome to server.\n!!! Enter a sentence : ", 46, 0); if (status == -1) { fprintf(stderr, "*** Server error: unable to send\n"); return; } /* Receive response from server */ nbytes = recv(cfd, buffer, MAX_LEN-1, 0); if (nbytes == -1) { fprintf(stderr, "*** Server error: unable to receive\n"); return; } buffer[nbytes] = '\0'; fprintf(stderr, "+++ Received sentence from client:\n"); fprintf(stderr, "+++ \t\"%s\"\n", buffer); /* Process response and send output to server */ wc = wordCount(buffer); sprintf(buffer, "!!! Number of words: %d\n", wc); send(cfd, buffer, strlen(buffer), 0); if (status == -1) { fprintf(stderr, "*** Server error: unable to send\n"); return; } /* Wind up */ status = send(cfd, "!!! Tschus!\n", 12, 0); if (status == -1) { fprintf(stderr, "*** Server error: unable to send\n"); return; } } /* Auxiliary routine used by clientTalk() */ int wordCount ( char *str ) { int wc = 0, i; while (1) { while ((*str == ' ') || (*str == '\t')) ++str; if (*str == '\0') break; ++wc; while ((*str != ' ') && (*str != '\t') && (*str != '\0')) ++str; } return wc; } int main () { int sfd; sfd = startServer(); serverLoop(sfd); } /*** End of server.c ***/