2

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/

Community
  • 1
  • 1
poundifdef
  • 18,726
  • 23
  • 95
  • 134

1 Answers1

3

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
  • 71,764
  • 9
  • 59
  • 54
  • 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! – poundifdef Feb 24 '09 at 07:57