title: C TCP Socket recv return -1 on Server-Server communication
body: <p>I am building a <code>client-server socket</code> simulation to emulate <code>DHCP</code>. I have a <code>client</code> that receives input from the user, then sends a request via <code>UDP</code> to <code>Server1</code>. If Server1 does not hold the requested information, it contacts <code>Server2</code> via <code>TCP</code>. If <code>Server2</code> does not hold the information, it contacts <code>Server3</code>. <code>Server3</code> then sends information to <code>Server2</code> then <code>Server1</code> then on to the <code>Client</code></p>
  
  <p>My code works for <code>Client --&gt; Server1 --&gt; Server2 --&gt; Server1 --&gt; Client</code>, but it fails when I try to add <code>Server3</code>.</p>
  
  <p><code>Server3</code> successfully receives the connection and data from <code>Server2</code>, and the <code>send</code> is successful I believe. However, the <code>recv</code> on server 2 returns <code>-1</code>.</p>
  
  <p>Here is my <code>Server3</code> send code:</p>
  
  <pre><code>while ((rqst = accept(svc,(struct sockaddr *) &amp;client_addr, &amp;alen)) &lt; 0) {
      /* we may break out of accept if the system call */
      /* was interrupted. In this case, loop back and */
      /* try again */
  } 
  inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
  recvlen = recv(rqst, buf, BUFSIZE - 1, 0);
  if (send(rqst, "Hello Server2!\0", BUFSIZE, 0) &lt; 0) { /* Not real message, but this works */
            perror("sendto");
  }
  </code></pre>
  
  <p>My <code>Server2 recv</code> code is here</p>
  
  <pre><code>int port = SERVICE_PORT3;      /* default: whatever is in port.h */
  char *host = "localhost";      /* default: this host */
  if (!conn_and_send(host, port, buf, fd3)) {    /* connect fd3 is global int */
    exit(1);   /* something went wrong */
  }
  else {
    char serv3_buf[BUFSIZE];
    int serv3_recvlen = recv(fd3, serv3_buf, BUFSIZE - 1, 0);
    printf("The recv length from serv3 is: %d\n", serv3_recvlen); /* prints -1*/
  }
  </code></pre>
  
  <p>This is my <code>conn_and_send</code> function</p>
  
  <pre><code>int conn_and_send(char *host, int port, char* request, int fd_sock)
  {
    struct hostent *hp;   /* host information */
    unsigned int alen;    /* address length when we get the port number */
    struct sockaddr_in myaddr;    /* our address */
    struct sockaddr_in servaddr;  /* server address */
  
    printf("conn(host=\"%s\", port=\"%d\")\n", host, port);
  
    if ((fd_sock = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0) {
      perror("cannot create socket");
      return 0;
    }
  
    memset((char *)&amp;myaddr, 0, sizeof(myaddr));
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    myaddr.sin_port = htons(0);
  
    if (bind(fd_sock, (struct sockaddr *)&amp;myaddr, sizeof(myaddr)) &lt; 0) {
      perror("bind failed");
      return 0;
    }
  
    alen = sizeof(myaddr);
    if (getsockname(fd_sock, (struct sockaddr *)&amp;myaddr, &amp;alen) &lt; 0) {
      perror("getsockname failed");
      return 0;
    }
    printf("local port number = %d\n", ntohs(myaddr.sin_port));
  
    memset((char*)&amp;servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
  
    hp = gethostbyname(host);
    if (!hp) {
      fprintf(stderr, "could not obtain address of %s\n", host);
      return 0;
    }
  
    memcpy((void *)&amp;servaddr.sin_addr, hp-&gt;h_addr_list[0], hp-&gt;h_length);
  
    if (connect(fd_sock, (struct sockaddr *)&amp;servaddr, sizeof(servaddr)) &lt; 0) {
      perror("connect failed");
      return 0;
    }
    printf("Getting ready to send: %s\n", request);
    if (send(fd_sock, request, strlen(request), 0) &lt; 0) {
      perror("sendto");
      exit(1);
    }
    return 1;
  }
  </code></pre>
  
  <p>Sorry to post so much code. I tried to include only relevant snippets.</p>
  
  <p>What am I doing wrong, and if you can see no problems besides my poor <code>C</code> coding, why does <code>C</code> hate me?! :P</p>