title: tcp socket, select tells writable, but write() blocks
body: <p>I wrote a little tcp socket server program, using select() to check if a client socket is writable. If the client is writable, I will write data to it.</p>
  
  <p>The client is written in Python, for testing only, it connect to the server, and never read from the connect.</p>
  
  <p>The result is, server write() finally blocks.</p>
  
  <p><strong>Server(C):</strong></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;arpa/inet.h&gt;
  #include &lt;netinet/tcp.h&gt;
  #include &lt;sys/select.h&gt;
  
  int main(int argc, char **argv){
      int serv_sock;
      struct sockaddr_in addr;
      const char *ip = "0.0.0.0";
      int opt = 1;
      int port = 7000;
      if(argc &gt; 2){
          port = atoi(argv[1]);
      }
  
      bzero(&amp;addr, sizeof(addr));
      addr.sin_family = AF_INET;
      addr.sin_port = htons((short)port);
      inet_pton(AF_INET, ip, &amp;addr.sin_addr);
  
      serv_sock = socket(AF_INET, SOCK_STREAM, 0);
      setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &amp;opt, sizeof(opt));
      bind(serv_sock, (struct sockaddr *)&amp;addr, sizeof(addr));
      listen(serv_sock, 1024);
  
      printf("server listen on port: %d\n", port);
  
      int sock = accept(serv_sock, NULL, NULL);
      printf("accepted\n");
  
      while(1){
          fd_set w_set;
          FD_ZERO(&amp;w_set);
          int maxfd = sock;
          FD_SET(sock, &amp;w_set);
          int ret = select(maxfd + 1, NULL, &amp;w_set, NULL, NULL);
          if(ret &lt; 0){
              if(errno == EINTR){
                  continue;
              }else{
                  printf("select error! %s\n", strerror(errno));
                  exit(0);
              }
          }
          char buf[128 * 1024];
          if(FD_ISSET(sock, &amp;w_set)){
              printf("write begin\n");
              int n = write(sock, buf, sizeof(buf));
              printf("write %d\n", n);
          }
      }
  
      return 0;
  }
  </code></pre>
  
  <p><strong>Client(Python):</strong></p>
  
  <pre><code>import socket
  s = socket.socket()
  s.connect(('127.0.0.1', 7000))
  </code></pre>
  
  <p><strong>Output:</strong></p>
  
  <pre><code>$ gcc a.c; ./a.out 
  server listen on port: 7000
  accepted
  write begin
  write 131072
  write begin
  write 131072
  write begin
  write 131072
  write begin
  write 131072
  write begin
  write 131072
  write begin
  </code></pre>
  
  <p>My qustion is: <strong>why would write() operation blocks even if select tells writable?</strong> The manual of select() says:</p>
  
  <blockquote>
    <p>A  file descriptor  is  considered  ready  if  it  is possible to
    perform the corresponding I/O operation (e.g., read(2)) without
    blocking.</p>
  </blockquote>