/*server.c -- The program implements as a concurrent server. It announces its availability as well as services it offers and on which ip address/port to the dispatcher.Once it has finished doing so, it will listen to the advertised ip address/port to service client calls. After a client connects to it, the server will do the according operation requested by client, and return the result directly back to client.*/ #include "service.h" int port; char dispatcher[100]; char myaddr[150]; int sockfd; int acsd; /*accept socket.*/ struct sockaddr_in my_addr; int myport=9003; int main(int argc ,char **argv) { char function[15]; int func=2; /*the server provides both sum and product function 0 is for "sum", 1 is for "product", 2 is for both "sum" and "product".*/ /*to handle the SIGINT and SIGCHLD */ signal(SIGINT,myhandler); signal(SIGCHLD,myhandler); if(argc<3) { printf("Usage: client dest port \n"); exit(-1); } strcpy(dispatcher,argv[1]); /*get the ip address of dispatcher.*/ port=atoi(argv[2]); /*get the port number of dispatcher.*/ if(func==0) strcpy(function,"sum"); else if(func==1) strcpy(function ,"product"); else strcpy(function ,"both"); provide_service(function); /*to provide the service*/ return 0; } /*A handler to handle the SIGINT and SIGCHLD to the server. */ void myhandler(int signum) { char info[100]; int status; /*Before termination, sever warns the dispatcher it is no longer available, ask the dispatcher to delete its information from the table.*/ if(signum==SIGINT) { close(sockfd); connect_remote(dispatcher,port,&sockfd,&my_addr); printf("Sending exit signal to the dispatcher ......"); sprintf(info,"%s %s %s %d","server","exit",myaddr,myport); /*send message to dispatcher, including "exit",server's ip address, server's port number (contained in info). */ send(sockfd,info,strlen(info)+1,0); printf("Done!\n"); close(sockfd); printf("Parent exited,child still working.\n"); exit(0); } if(signum==SIGCHLD) { pid_t child_pid;//the ending child's pid child_pid=wait(&status); signal(SIGCHLD, SIG_IGN);//ignore other SIGCHLD if(WIFEXITED(status)) { fprintf(stdout,"\nfork()ed child %d exited normally\n",child_pid); fflush(stdout); } else { fprintf(stderr,"Hmm...child did not exit normally\n"); fflush(stderr); } fprintf(stdout,"Client serviced, process terminated\n\n"); fflush(stdout); signal(SIGCHLD,myhandler); return; } }