/* NAME : server.C TYPE : C++ SOURCE AUTHOR : Arunkumar Elango DESCRIPTION : This file contains the source code for the server. It takes the following command line as input : $ server [-p portnumber] It creates and binds a socket at the either the well known portnumber or at the portnumber given in the commandline. Then, it waits for a connection request from a client. When the request arrives, it reads the socket, to get the string to be echoed. It then writes out this same string with a "Server echo : " prefix, back to the socket. */ #include #include #include #include #include #include #include #include //#include #include #include #include #include //#include const int MAXSTR=1024; // Maximum String length const long PORTNUM=54715; // The "Well-known" port number //const int PASSWORD = 21; // The password that the server expects. void handleRequest(int); // Function to handle clients' request(s) //int numberChildren; // The current number of child processes. //void childExit(int); // signal handler for SIGCHLD main( int argc, char *argv[]) { int portNumber; //char executableName[MAXSTR]; //struct sigaction action; // Validate and read from the command line if ( (argc != 3) && (argc != 1) ) { cerr << "Invalid command line.\n"; exit(1); } if ( argc == 1 ) { portNumber = PORTNUM; } else { if (!strcmp(argv[1],"-p")) { portNumber = atoi(argv[2]); } else { cerr << "Invalid command line.\n"; exit(1); } } if (portNumber < 10000) { cerr << "Port number has to be atleast 10000.\n"; exit(1); } // At this point, the command line has been validated. int sockfd,newsockfd,clilen,childpid; struct sockaddr_in serv_addr,cli_addr; // Create a new TCP socket... if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { cerr << "Cant open stream socket.\n"; exit(0); } bzero((char *)&serv_addr,sizeof(serv_addr)) ; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(portNumber); // Bind the socket to the server's ( this process ) address. if (bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) { cerr << "Cant bind local address.\n"; exit(1); } // Listen for connections in this socket listen(sockfd,5); int status; cerr << " Connected to port : " << portNumber << "\n"; char buf[MAXSTR],ack[MAXSTR]; // repeat forever.. while (1) { clilen = sizeof(cli_addr); // Accept a client's request, and get the client's address info into the local variable cli_addr. newsockfd = accept(sockfd,(struct sockaddr *)&cli_addr,&clilen); // After accepting the connection, all transaction with this client would happen with the new socket descriptor - newsockfd. if ((newsockfd < 0) && (errno != EINTR)) cerr << " server : accept error.\n"; else if (newsockfd > 0) { handleRequest(newsockfd); close(newsockfd); } } } void handleRequest(int newsockfd) { char buf[MAXSTR],execName[MAXSTR],ack[MAXSTR]; char data[MAXSTR]; // Read from the socket, for the password and the requested command. read(newsockfd,(void *)buf,MAXSTR); sscanf(buf,"%s\n",execName); sprintf(ack,"Server echo : %s",execName); cout << "From client: " << execName << endl; // Write back the response to the socket write(newsockfd,ack,strlen(ack)); }