views:

604

answers:

1

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.

http://stackoverflow.com/questions/575602/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/

+2  A: 

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:

signal(SIGPIPE, SIG_IGN);

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).

codelogic
Ah, in gdb I did notice a SIGPIPE, but I couldn't for the life of me figure out why that was. And I didn't realize that not checking for that (being an incomplete program) would be so catastrophic. Thank you so much!
rascher