Problem with tcp server

Hello @ all,

I hope you can give me some advice :b:

I will be following code for a tcp server and doStuff () function, the
clients treated. From some point, I have several identical
clients (zombies, I think), the same records in the database
write. Has anyone an explanation? What can I do?

int main(int argc, char *argv[])
{
     int srvrSock;                        /* Socket descriptor for server */
     int clntSock;                        /* Socket descriptor for client */
     struct sockaddr_in echoServAddr;     /* Local address */
     struct sockaddr_in echoClntAddr;     /* Client address */
     unsigned short echoServPort;         /* Server port */
     unsigned int cliAddrLen;             /* Length of incoming message */
     int pid;
     struct sigaction sa;
     int loop;

     char ip[16];

     /* Test for correct number of parameters */
     if (argc < 2) {
         fprintf(stderr,"Verwendung:  %s <TCP SERVER PORT>\n", argv[0]);
         exit(1);
     }
     //end if

     /* First arg:  local port */
     echoServPort = atoi(argv[1]);

     /* Create socket for sending/receiving */
     if ((srvrSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
         DieWithError("socket() failed");
     //end if

     /* Construct local address structure */
     memset(&echoServAddr, 0, sizeof(echoServAddr));   /* Zero out 
structure */
     echoServAddr.sin_family = AF_INET;                /* Internet 
address family */
     echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming 
interface */
     echoServAddr.sin_port = htons(echoServPort);      /* Local port */

     /* Bind to the local address */
     if (bind(srvrSock, (struct sockaddr *) &echoServAddr, 
sizeof(echoServAddr)) < 0)
         DieWithError("ERROR on binding");
     //end if

     /* Listen */
     if (listen(srvrSock,5)<0)
         DieWithError("listen() failed");
     //end if

     sa.sa_handler = sigchld_handler; // reap all dead processes
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_RESTART;
     if (sigaction(SIGCHLD, &sa, NULL) == -1) {
         perror("sigaction");
         exit(1);
     }


     /* Set the size of the in-out parameter */
     cliAddrLen = sizeof(echoClntAddr);

     while (1) {
         printf(" loop %d \n\n", loop);
         loop++;

         /* Wait for a client to connect */
         if ((clntSock = accept(srvrSock, (struct sockaddr *) 
&echoClntAddr, &cliAddrLen)) < 0)
             DieWithError("accept() failed");
         //end if

         /* clntSock is connected to a client! */
         strcpy(ip,inet_ntoa(echoClntAddr.sin_addr));
         printf("Handling client %s\n", ip);

         pid = fork();
         if (pid < 0)
         {
         DieWithError("ERROR on fork");
         }
         else if (pid == 0)
         {
             close(srvrSock);
             dostuff(clntSock,ip);
             close(clntSock);
             exit(0);
         }
         else close(clntSock);

     } /* end of while */

     return 0; /* we never get here */
}

--

Best regards
Burak Senel

not: sorry, for my bad english... and thank you PLUDI

Do you know if sigchld_handler is actually being called?

Furthermore, whenever sigchld_handler is called, be sure to check for more than one child. SIGCHLD signals won't queue up if there's more than one, it'll just be missed. Which is annoying since you can't guarantee there'll never be a zombie with a callback but at least you can stop them from accumulating...

I don't see anything to do with a database here so it's impossible to be sure, but is it possible you're storing a pointer to the ip char array instead of a copy of its contents? That would mean every entry in whatever your database is would show the most recent IP address.