title: select monitor two socket and return 1 instead of 2
body: <p>server <code>send</code> &quot;hello&quot; after accept two client.</p>
  <p>client <code>recv</code> &quot;hello&quot; and <code>send</code> something <strong>infintely</strong>.</p>
  <p>Then, server uses <code>select()</code> waiting for data from two <code>socket_fd</code>.</p>
  <p>I support that <code>select()</code> could detect if <code>socket_fd</code> had data in its buffer and result would be <strong>2</strong>.</p>
  <p>Acturally, it return <strong>1</strong> after some <strong>2</strong>.</p>
  <p>In wireshark, it caused a <strong>zero-window</strong>.</p>
  <p>How can I fix it?</p>
  <p>My simplfied code:</p>
  <pre class="lang-cpp prettyprint-override"><code>// server.cpp
  #include &lt;cstdio&gt;
  #include &lt;cstring&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;sys/select.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;unistd.h&gt;
  
  struct sockaddr_in  ser_addr, cli_addr[2];
  int                 lisn_fd, conn_fd[2];
  fd_set              fs;
  socklen_t           len;
  char                buff[4096];
  
  int main() {
      ser_addr.sin_family = AF_INET;
      ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      ser_addr.sin_port = htons(9876);
      
      lisn_fd = socket(AF_INET, SOCK_STREAM, 0);
      bind(lisn_fd, (struct sockaddr*) &amp;ser_addr, sizeof(ser_addr));
      listen(lisn_fd, 10);
  
      FD_ZERO(&amp;fs);
  
      for (int i = 0; i &lt; 2; i++) {
          conn_fd[i] = accept(lisn_fd, (struct sockaddr*) &amp;cli_addr[i], &amp;len);
          FD_SET(conn_fd[i], &amp;fs);
      }
      int maxfd = conn_fd[0] &gt; conn_fd[1]? conn_fd[0] : conn_fd[1];
      while (1) {
          write(conn_fd[0], &quot;hello&quot;, 5);
          write(conn_fd[1], &quot;hello&quot;, 5);
          int nready = select(maxfd+1, &amp;fs, NULL, NULL, NULL);
          printf(&quot;nread = %d\n&quot;, nready);
          
          for (int i = 0; i &lt; 2; i++) {
              if ( FD_ISSET(conn_fd[i], &amp;fs) ) {
                  printf(&quot;recv from client %d\n&quot;, i+1);
                  ssize_t nread = read(conn_fd[i], buff, 4096);
                  buff[nread] = 0;
                  // puts(buff);
              }
          }
      }
      return 0;
  }
  </code></pre>
  <pre class="lang-cpp prettyprint-override"><code>// client.cpp
  
  #include &lt;arpa/inet.h&gt;
  #include &lt;cstdio&gt;
  #include &lt;cstring&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;unistd.h&gt;
  
  struct sockaddr_in  ser_addr;
  int                 conn_fd;
  
  
  int main(){
      ser_addr.sin_family = AF_INET;
      ser_addr.sin_port = htons(9876);
      inet_pton(AF_INET, &quot;127.0.0.1&quot;, &amp;ser_addr.sin_addr);
      conn_fd = socket(AF_INET, SOCK_STREAM, 0);
      connect(conn_fd, (struct sockaddr*) &amp;ser_addr, sizeof(ser_addr));
      
      char buff[4096];  
      buff[read(conn_fd, buff, 4096)] = 0;
      printf(&quot;recv: %s\n&quot;, buff);
      sprintf(buff, &quot;hello from %d&quot;, getpid());
      while (1) {
          sleep(1);
          write(conn_fd, buff, strlen(buff));
      }
  
      return 0;
  }
  </code></pre>
  <pre class="lang-sh prettyprint-override"><code>$ ./server
  recv from client 1
  recv from client 2
  nread = 2
  recv from client 1
  recv from client 2
  nread = 2
  recv from client 1
  recv from client 2
  nread = 2
  recv from client 1
  recv from client 2
  nread = 1
  recv from client 1
  nread = 1
  recv from client 1
  nread = 1
  recv from client 1
  nread = 1
  recv from client 1
  nread = 1
  recv from client 1
  ^C
  </code></pre>
  <pre class="lang-sh prettyprint-override"><code>$ ./client
  recv: hello
  </code></pre>
  <pre class="lang-sh prettyprint-override"><code>$ netstat -anp | rg server
  (Not all processes could be identified, non-owned process info
   will not be shown, you would have to be root to see it all.)
  Active Internet connections (servers and established)
  tcp        0      0 0.0.0.0:9876            0.0.0.0:*               LISTEN      13805/./server      
  tcp     2160      0 127.0.0.1:9876          127.0.0.1:54694         ESTABLISHED 13805/./server      
  tcp        0      0 127.0.0.1:9876          127.0.0.1:54696         ESTABLISHED 13805/./server 
  </code></pre>
  <p>=================UPDATE===================</p>
  <p>I don't expect sockets are alyways ready and the result is always 2.</p>
  <p>The problem is if turn into 1, it will be 1 <strong>forever</strong>.</p>
  <p>And I found a solution, but it is confusing.</p>
  <pre class="lang-cpp prettyprint-override"><code>// server.cpp
  // ommit others
  while (1) {
      // clear &amp; reset fd_set before using select
      FD_ZERO(&amp;fs);
      FD_SET(conn_fd[0], &amp;fs);
      FD_SET(conn_fd[1], &amp;fs);
  </code></pre>
  <p>I reset the <code>fd_set</code>, and the <strong>1</strong> and  <strong>2</strong> will staggered appear.</p>
  <p>Is <code>select()</code> will change somthing?</p>