title: "bind: address already in use" even with SO_REUSEADDR set
body: <p>I've written a simple echo server, which includes the following line:</p>
  
  <pre><code>int yes = 1;
  if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &amp;yes, sizeof(int)) == -1) {
      perror("setsockopt");
      exit(1);
  }
  </code></pre>
  
  <p>However despite this, I'm still getting an error when I try to call <code>bind</code> on a socket I've recently used. In fact, I'm getting this error if I try to call <code>bind</code> on a socket I've used in this program, period, even if it's not recent - like they're not being cleared by the kernel or something. Is there something else I have to do?</p>
  
  <p>Here's the full code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;netdb.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;unistd.h&gt;
  
  void prepareHints(struct addrinfo *hints, int tcp_udp) {
      memset(hints, 0, sizeof(struct addrinfo));
      hints-&gt;ai_family = AF_UNSPEC;
      hints-&gt;ai_socktype = (tcp_udp == 1) ? SOCK_STREAM : SOCK_DGRAM;
      hints-&gt;ai_flags = AI_PASSIVE; /* autofill IP */
  }
  
  void writeSocket(int fd, const char *msg) {
      size_t nbytes = 0;
      size_t len = strlen(msg);
      while (nbytes &lt; len)
          nbytes += send(fd, msg, len, 0);
  }
  
  void waitLoop(int sockfd) {
      int clientfd, nbytes;
      struct sockaddr addr;
      socklen_t len;
      char buf[512];
      while(1) {
          clientfd = accept(sockfd, &amp;addr, &amp;len);
          if (clientfd &lt; 0) {
              perror("accept");
              exit(1);
          }
          while ((nbytes = recv(clientfd, buf, 512, 0)) != EOF) {
              buf[nbytes] = '\0';
              strcat(buf, "\r\n");
              writeSocket(clientfd, buf);
          }
          close(clientfd);
      }
  }
  
  int main(int argc, char **argv) {
      const char *port = (argc &gt;= 2) ? argv[1] : "7474";
      struct addrinfo hints, *res;
      prepareHints(&amp;hints, 1);
  
      int status = getaddrinfo(NULL, port, &amp;hints, &amp;res);
      if (status != 0) {
          printf("Error on getaddrinfo\n");
          exit(1);
      }
  
      /* scan through sockaddr's returned by getaddrinfo until we successfully set up a socket with one */
      int socketfd;
      struct addrinfo *cur;
      for (cur = res; cur != NULL; cur = cur-&gt;ai_next) {
          if ((socketfd = socket(res-&gt;ai_family, res-&gt;ai_socktype, res-&gt;ai_protocol)) &gt;= 0)
              break;
      }
      /* make sure we actually found one */
      if (socketfd == -1) {
          printf("Error on socket\n");
          exit(1);
      }
      /* bind the socket to the struct sockaddr_in contained in res */
      int bindres = bind(socketfd, cur-&gt;ai_addr, cur-&gt;ai_addrlen);
      if (bindres != 0) {
          perror("bind");
          exit(1);
      }
  
      int yes = 1;
      if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &amp;yes, sizeof(int)) == -1) {
          perror("setsockopt");
          exit(1);
      }
  
      if (listen(socketfd, 5) &lt; 0) {
          printf("error on listen\n");
          exit(1);
      }
  
      printf("success, listening on socket %d, port %d\n", socketfd, ntohs(((struct sockaddr_in *)res-&gt;ai_addr)-&gt;sin_port));
      waitLoop(socketfd);
      return 0;
  }
  </code></pre>