/* tcp.slave.fork.c SJ */ /* gcc -Wall -o tcp.slave tcp.slave.c -lnsl -lsocket -lresolv */ #include #include #include #include #include #include #include #include #include #include #include #include void sendall(int sock, char *buf); /* signal handler to wait all child processes */ void sigchld_handler(int s) { while(wait(NULL) > 0); } int main(int argc, char **argv) { int j; int numbytes, count, pid; char buf[1000]; char mesg2[100]; char hname[100]; struct sockaddr_in remote_addr, my_addr; int sock, newsock; int sin_size; char yes='1'; struct sigaction sa; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (gethostname(hname, 99) == -1) { perror("gethostname"); strcpy(hname, "???"); } my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(atoi(argv[1])); // short, network byte order my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct /* bind to the port */ if (bind(sock, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } /* open port for connections */ if (listen(sock, 5) == -1) { perror("listen"); exit(1); } /* register signal handler which waits (ackknowledges) all childs */ sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } /* serve forever */ while(1) { sin_size = sizeof(struct sockaddr_in); /* accept new connection */ if ((newsock = accept(sock, (struct sockaddr *)&remote_addr, &sin_size)) == -1) { perror("accept"); continue; } printf("got connection from %s\n",inet_ntoa(remote_addr.sin_addr)); /* create child process to handle the new connection */ pid = fork(); if (!pid) { /* child process, handle one request */ numbytes = recv(newsock, buf, 999, 0); if (numbytes == -1) { perror("recv"); close(newsock); exit(1); } buf[numbytes] = '\0'; /* terminate string */ count = atoi(buf); /* convert to int */ /* print */ puts(buf); /* send message */ sprintf(mesg2, "Hello from %s(pid=%d)\n", hname, getpid()); for (j = 0; j < count; j++) { sendall(newsock, mesg2); } /* close and exit */ close(newsock); exit(0); } /* parent just closes newsock */ close(newsock); } close(sock); exit(0); } void sendall(int sock, char *buf) { int len, bs; len = strlen(buf); while (len > 0) { bs = send(sock, buf, len, 0); if (bs == -1) { perror("send"); return; } else if (bs == 0) { printf("Connection closed prematurely\n"); return; } len -= bs; } } /* sendall() */