title: C socket programming client sometimes don't receive server mesage
body: <p>I made a simple client program with C that sends HTTP request to a host. The last part of the code, where the client receives HTTP response from server looks like this:</p>
  <pre class="lang-c prettyprint-override"><code>int main(int argc, char *argv[])
  {
      // ...
      
      char buf[BUFSIZ];
      int content_length;
  
      content_length = recv(clientfd, buf, sizeof(buf) - 1, 0);
      buf[content_length] = 0;
  
      printf(&quot;%s&quot;, buf);
  
      fflush(stdout);
      exit(EXIT_SUCCESS);
  }
  </code></pre>
  <p>With this code, I often get the expected result like the following:</p>
  <pre><code>GET /foo HTTP/1.0
  Host: 127.0.0.1:8080
  
  HTTP/1.0 200 OK
  Content-Length: 12
  Connection: close
  
  abadakedavra   
  </code></pre>
  <p>But sometimes, the content of the request doesn't show up.</p>
  <pre><code>GET /foo HTTP/1.0
  Host: 127.0.0.1:8080
  
  HTTP/1.0 200 OK
  Content-Length: 12
  Connection: close
  
  </code></pre>
  <p>What could be the reason for this behavior?</p>
  <p>cf. My whole client code looks like this:</p>
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;errno.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;netdb.h&gt;
  
  #define MAX_REQUEST     10000
  #define MAX_URL         2048
  
  void error(const char *msg)
  {
      perror(msg);
      exit(EXIT_FAILURE);
  }
  
  void parse_url(char *src, char *hostname, char *port, char *url)
  {
      size_t i, j = 0;
  
      for (i = 7; src[i] != ':'; i++)
          hostname[j++] = src[i];
      hostname[j] = 0;
  
      j = 0;
      for (i = i + 1; src[i] != '/'; i++)
          port[j++] = src[i];
      port[j] = 0;
  
      j = 0;
      for (i = i + 1; src[i]; i++)
          url[j++] = src[i];
      url[j] = 0;
  }
  
  int main(int argc, char *argv[])
  {
      /* 
      Expect
      argv[0] : ./client (Executable name)
      argv[1] : -G (GET) or -P (POST)
      argv[2] : http://hostname:port/url
      */
  
     
      int clientfd;
      char hostname[MAX_URL], port[6], url[MAX_URL];
      char msg[MAX_REQUEST];
      struct addrinfo hints, *listp, *p;
  
      if (argc &lt; 3 || (strcmp(argv[1], &quot;-G&quot;) != 0 &amp;&amp; strcmp(argv[1], &quot;-P&quot;) != 0))
      {
          printf(&quot;Usage:\n        %s -P &lt;URL&gt;        HTTP 1.0 POST from stdin\n&quot;
                 &quot;        %s -G &lt;URL&gt;        HTTP 1.0 GET to stdin\n&quot;,
                 argv[0], argv[0]);
          exit(EXIT_FAILURE);
      }
      parse_url(argv[2], hostname, port, url);
      if(strcmp(argv[1], &quot;-P&quot;) == 0) fgets(msg, MAX_REQUEST, stdin);
      
      /* Client socket creation */
  
      memset(&amp;hints, 0, sizeof(struct addrinfo));
      hints.ai_socktype = SOCK_STREAM; // Use TCP
      hints.ai_flags = AI_NUMERICSERV; // Use numeric port arg
  
      // Generate a list of addrinfo in listp
      getaddrinfo(hostname, port, &amp;hints, &amp;listp);
  
      for (p = listp; p; p = p-&gt;ai_next)
      {
          // Create a socket based on addrinfo struct
          if ((clientfd = socket(p-&gt;ai_family, p-&gt;ai_socktype, p-&gt;ai_protocol)) &lt; 0)
              continue;
          if (connect(clientfd, p-&gt;ai_addr, p-&gt;ai_addrlen) != -1)
              break;
          close(clientfd); // Bind fail, loop to try again
      }
  
      freeaddrinfo(listp); // Not needed anymore
  
      if (!p) // Entire loop failed
      {
          error(&quot;Failed in socket binding&quot;);
      }
  
  
      /* Send HTTP Request */
  
      char httpRequest[MAX_REQUEST];
  
      if(strcmp(argv[1], &quot;-G&quot;) == 0) sprintf(httpRequest, &quot;GET /%s HTTP/1.0\r\nHost: %s:%s\r\n\r\n&quot;, url, hostname, port);
      else if(strcmp(argv[1]), &quot;-P&quot; == 0) sprintf(httpRequest, &quot;POST /%s HTTP/1.0\r\nHost: %s:%s\r\nContent-Type: plain/text\r\nContent-Length: %lu\r\n\r\n%s\n&quot;, url, hostname, port, strlen(msg), msg);
      else error(&quot;Invalid request&quot;);
  
      printf(&quot;%s&quot;, httpRequest);
      send(clientfd, httpRequest, strlen(httpRequest), 0);
  
      /* Recieve HTTP response */
  
      char buf[BUFSIZ];
      int content_length;
  
      content_length = recv(clientfd, buf, sizeof(buf) - 1, 0);
      buf[content_length] = 0;
  
      printf(&quot;%s&quot;, buf);
  
      fflush(stdout);
      exit(EXIT_SUCCESS);
  }
  
  
  
  </code></pre>