I am writing a server program in C wherein every time a client connects, I create a new pthread to handle the client’s requests.
When all of the threads exit, however, then my program exits, as though a call to exit() has been made. This is a problem – how can I overcome it?
Lets say the server is running, and 2 clients connect. Once those clients disconnect – and thus both threads exit – then my server process exits. What I want is for my server to keep accept()ing socket requests. Ususally this works when I use fork() and accept(). What am I doing wrong such that the parent process is terminating rather than looping infinitely?
Code looks basically like this:
void *talker( void *d ) { int fd; char buf[] = 'Hello client'; fd = (int)d; while( 1 ) { write( fd, buf, strlen( buf )+1 ); sleep(4); } } int main( int argc, char *argv[] ) { pthread_t thread[50]; int sockfd; struct sockaddr_in client_addr; int i = 0; int s1; /* ... other declarations */ if (initialize_server_socket(portno, &sockfd) < 0) { fprintf(stderr, 'Could not initialize socket\n'); exit(-1); } while( 1 ) { s1 = accept( sockfd, (struct sockaddr *)&client_addr, &n ); pthread_create( &(thread[i++]), NULL, talker, (void *)s1 ); } return(0); }
Also: this is the same project from a question I already asked (linked below)… though after spending too much time trying to use select() and IPC unsuccessfully, I figured I’d give threads a whirl because of the simplicity of shared address space.
Using pipes in C for parent-child IPC makes program block
Also, much of this code was taken from here: http://www.s5h.net/2006/06/27/pthread-socket-server-in-c/
If you debug it in gdb you’ll see that you’re getting a SIGPIPE, which your program doesn’t handle. You can either install a SIGPIPE handler or ignore SIGPIPE.
The reason is that your thread is writing to a socket (pipe) that has been closed (by the client), which raises a SIGPIPE. You should check the return value of
write()after ignoring SIGPIPE:or handle SIGPIPE. It has nothing to do with 2 clients connecting, if you wait for 4 seconds after the client disconnects, you’ll get a SIGPIPE (in your case).