title: TCP concurrent echo server unable to read string from first client
body: <p>I am implementing a simple TCP process-per-client concurrent echo server. The server is unable to read string from first client. However for further clients, the server echoes back the string correctly. I felt that it might be some issue with reading string; the server-end being unable to detect EOF. I tried using send()/recv() instead of read()/write() with no success. I also tried other functions for reading string from stdin - namely fgets(), scanf() etc.   </p>
  
  <p>What is the possible cause for this problem ; i.e. server being unable to read only from first client?</p>
  
  <p>The code for server and client is below - </p>
  
  <pre><code>// server.c
  #include &lt;signal.h&gt;
  #include &lt;sys/wait.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;string.h&gt;
  #define BUF_SIZE 4096
  #define MAXPENDING 256
  
  static void zombieReaper(int sig)
  {
      while (waitpid(-1, NULL, WNOHANG) &gt; 0)
          continue;
  }
  
  static void handleRequest(int cfd)
  {
      char buf[BUF_SIZE];
      int numread;
      int size = BUF_SIZE;
      int i;
  
      printf("\n inside handling request fd : %d ", cfd);
      fflush(stdout);
  
      while (1) {
          numread = read(cfd, buf, size);
          if (numread &gt; 0) {
              int l = strlen(buf);
              printf("Echo server numread : %d len : %d buf : %s\n", numread, l, buf);
              fflush(stdout);
              buf[l] = '\0';
              write(cfd, buf, size);
          }
      }
  }
  
  int main(int argc, char *argv[])
  {
      int lfd, cfd;
      struct sigaction sa;
  
      sigemptyset(&amp;sa.sa_mask);
      sa.sa_handler = zombieReaper;
      if (sigaction(SIGCHLD, &amp;sa, NULL) == -1) {
          printf("SIGCHILD signal");
          exit(0);
      }
  
      struct sockaddr_in serv_addr, clnt_addr;
      lfd = socket(AF_INET, SOCK_STREAM, 0);
      if (lfd == -1) {
          printf("Socket Failed");
          exit(0);
      }
  
      serv_addr.sin_family = AF_INET;
      serv_addr.sin_port = htons(atoi(argv[1]));
      serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  
      if (bind(lfd, (struct sockaddr *) &amp;serv_addr, sizeof(serv_addr)) &lt; 0) {
          printf("bind() failed");
          exit(0);
      }
  
      if (listen(lfd, MAXPENDING) &lt; 0) {
          printf("listen() failed");
          exit(0);
      }
  
      socklen_t clen = sizeof(clnt_addr);
      int status = 0;
      for (;;) {
          if (cfd = accept(lfd, (struct sockaddr *) &amp;clnt_addr, &amp;clen) &lt; 0) {
              printf("accept() failed");
          } else {
              printf("Accepted client cfd : %d\n", cfd);
              switch (fork()) {
              case -1:
                  close(cfd);
                  break;
              case 0:            // Child
                  close(lfd);
                  handleRequest(cfd);
                  exit(1);
              default:           // Parent
                  close(cfd);
                  break;
              }
          }
      }
  }
  
  // client.c
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;unistd.h&gt;
  #define BUF_SIZE 4096
  
  int main(int argc, char *argv[])
  {
      int clnt_fd;
      struct sockaddr_in serv_addr;
      //memset(&amp;serv_addr, 0, sizeof(serv_addr));
      char cmd[BUF_SIZE];
      char buf[BUF_SIZE];
  
      clnt_fd = socket(PF_INET, SOCK_STREAM, 0);
      if (clnt_fd == -1) {
          printf("socket() failed");
          exit(0);
      }
  
      // prepare for connect
      serv_addr.sin_family = AF_INET;
      serv_addr.sin_port = htons(atoi(argv[2]));
      serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
  
      // connect to server
      if (connect(clnt_fd, (struct sockaddr *) &amp;serv_addr, sizeof(serv_addr)) &lt; 0) {
          printf("connect() failed");
          exit(0);
      }
  
      int size = BUF_SIZE;
      while (1) {
          printf("\n Enter a string (q to Exit) : \n ");
          gets(cmd);
          if (!strcmp(cmd, "q"))
              break;
  
          int n = write(clnt_fd, cmd, strlen(cmd));
          n = read(clnt_fd, buf, BUF_SIZE);
          printf("\n Received Results : \n %s\n", buf);
      }
      close(clnt_fd);
  
      return 0;
  }
  </code></pre>