#include "service.h"
extern int port;
extern char dispatcher[100];
extern char function[15];
extern char myaddr[150];
extern int sockfd;
extern int acsd; /*accept socket.*/
extern struct sockaddr_in my_addr;
extern int myport;
int provide_service(char *function)
{
int pid;
char buff[100];
int status=0;
char info[100];
int a,b,c;
char name[150];
struct hostent *h;
struct sockaddr_in client_addr;
int len=sizeof(client_addr);
/*BEGINE TO CONNECT TO DISPATCHER */
printf("Connecting the dispatcher ......");printf("%s %d\n",dispatcher,port);
connect_remote(dispatcher,port,&sockfd,&my_addr);
/*server get the ip address of itself,put it in myaddr.*/
gethostname(name,100);
sprintf(myaddr,"%s",name);
/*send message to dispatcher, including its service, ip address and
port(contained in info). */
sprintf(info,"%s %s %s %d","server",function,myaddr,myport);
printf("Sending my info to the dispatcher ......");
if(send(sockfd,info,strlen(info)+1,0)<0)
{ perror("send");
exit(-1);
}
printf("Done!\n");
close(sockfd);
/*BEGINE TO WAIT FOR INCOMING CONNECTION FROM CLIENT.*/
printf("Listenning to clients ......");
if(bind_remote(myport,&sockfd,&my_addr)!=0) exit(-1);
printf("OK!\n");
while(1) /*forever, until receive SIGINT. */
{
if ((acsd = accept(sockfd, (struct sockaddr *) &client_addr, &len)) < 0)
{
if(errno==EINTR)
continue;
else
{
perror("accept");
exit (-1);
}
}
/*spawn a new process to handle client request.*/
pid = fork();
if (pid <0) /*error in creating a child process*/
{
perror("fork");
exit(-1);
}
if (pid == 0) /*this is the child.*/
{
/*The child does not need to access the listening socket,
only the parent does.*/
close(sockfd);
signal(SIGINT,SIG_IGN);
printf("I am %s, working now\n",myaddr);
printf("Receiving operands from %s at port %d......",
inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
/* buff[0]='\0';*/
/*receive message from client, including the service requested, and
the operands.*/
if(recv(acsd,buff,100, 0)==-1) exit(-1);
printf("Done!\n");
/*abstract the function and operands out.*/
sscanf(buff,"%s %d %d",function ,&a,&b);
/* buff[0]='\0';*/
printf("Computing ......");
fflush(stdout);
sleep(DELAY);/*sleep 30s to emulate major computation*/
if(strcmp(function,"sum")==0) c=a+b; /*sum operation.*/
else c=a*b; /*product operation.*/
sprintf(buff,"%d",c); /*put the result in d*/
printf("Done!\n");
printf("Sending result to client %s at port %d......",
inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
if(send(acsd, (void *) buff, strlen(buff) + 1, 0)==-1)
exit(-1);
printf("Done!\n");
/*As the service is finished, the socket is no longer usable by
this process.*/
close(acsd);
printf("Child %d finished procesing, exiting now.\n",getpid());
/*the child terminates */
exit(0);
}
if (pid > 0) /*this is the parent.*/
/*The parent process only listens for new connections and does not
need the client-connection socket.*/
close(acsd);
}
close(sockfd);
return (0);
}