Jerry Mcguire |
02-25-2014 02:29 AM |
Socket program and fork()
Hi, I'm puzzled with the piece of code. It is a TCP server program that is supposed to handle multiple incoming connections. First I tried without FORKING and the outcome was expected: When the function some_connection_handler() exits, the client knows immediately about the disconnection.
But when I tried with FORKING, and when some_connection_handler() exited, the client didn't know. What is wrong?
Error checking skipped for easier reading..
Code:
// ...
//Create socket
int servSock = socket( PF_INET, SOCK_STREAM, 0 );
//Set non-blocking
int n = fcntl( servSock, F_GETFL );
fcntl( servSock, F_SETFL, n | O_NONBLOCK );
//Set socket options
int opt = 1;
setsockopt( servSock, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt) );
setsockopt( servSock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt) );
//Fill in the address of the server ip and port
struct sockaddr_in servAddr;
memset( &servAddr, 0, sizeof(servAddr) );
// ... some details skipped ...
servAddr.sin_family = AF_INET;
bind( servSock, (struct sockaddr *)&servAddr, sizeof(servAddr) );
listen( servSock, SOMAXCONN );
fd_set rfds;
struct timeval tv;
int retval;
tv.tv_sec = 0;
tv.tv_usec = 100;
while (1) {
FD_ZERO(&rfds);
FD_SET(servSock, &rfds);
retval = select( servSock+1, &rfds, NULL, NULL, &tv );
if (retval == -1) {
perror("select()");
break;
}
else if (retval && FD_ISSET(servSock, &rfds)) {
int clntSock = accept( servSock, (struct sockaddr *)NULL, NULL );
#ifdef FORKING
pid_t pid = fork();
if (pid == -1) {
perror( "fork()" );
break;
}
else if (pid == 0) {
some_connection_handler( clntSock );
close( clntSock );
break;
}
#else
some_connection_handler( clntSock );
close( clntSock );
#endif
}
else {
if (some_quit_condition()) break;
}
}//while(1)
close( servSock );
//...
|