title: Using poll() for a TCP server in C
body: <p>For a school assignment we have to make a sensor gateway which has an input from multiple sensors that connect through TCP. We recieved a library that we can use for the TCP sockets. Whenever a sensor node gets disconnected, it has to be logged and certain data functions have to be called. I used poll() to multiplex the I/O of the gateway but the problem is, that it is not working correctly. I made a prototype of my gateway connection code below. It has the same problem so I presume I'm doing something wrong with poll() but I don't know what.</p>
  
  <p>Here is my code for the server:</p>
  
  <pre><code>int main( void )
  {
  Socket server; 
  Socket client[6];
  int client_count = 0;
  struct pollfd poll_list[7];
  
  // open server socket
  server = tcp_passive_open( PORT );
  poll_list[0].fd = get_socket_descriptor( server ); 
  poll_list[0].events = POLLIN;
  
  while( 1 ) {    
    int retval, i;
  
    retval = poll(poll_list, client_count+1, 5000);
    if (retval &gt; 0) {
        if (poll_list[0].revents &amp;&amp; POLLIN &gt; 0) {
            client[client_count] = tcp_wait_for_connection( server );
            poll_list[client_count+1].fd = get_socket_descriptor(client[client_count]);
            poll_list[client_count+1].events = POLLIN;
            client_count++;
        }    
        for (i=0; i&lt;client_count+1;i++) 
    {
            if ( poll_list[i+1].revents &amp; POLLIN)) 
        {
        printf("New message recieved.");
                tcp_receive(client[i], buffer, BUFFSIZE); 
        fflush(stdout);
  
            }
        if ( poll_list[i+1].revents &amp; POLLHUP) 
        {
        printf("Client disconnected.");
                poll_list[client_count+1].fd = -1;
                poll_list[client_count+1].events = 0;
        fflush(stdout);   
            }
        }
    }
  }
  
  tcp_close( &amp;server ); 
  return 0;
  }
  </code></pre>
  
  <p>Here is the code for the client:</p>
  
  <pre><code>int main( void ) {
  Socket client;
  char msg[] = "Hello there! Anyone?";
  
  // open TCP connection to the server; server is listening to SERVER_IP and PORT
  client = tcp_active_open( PORT, SERVER_IP ); 
  
  // send msg to server
  tcp_send( client, (void *)msg, strlen(msg)+1 ); 
  
  printf("\n");  
  
  // exit
  tcp_close( &amp;client );
  return 1;
  }
  </code></pre>
  
  <p>EDIT: The functions of the library files:</p>
  
  <pre><code>Socket tcp_passive_open(int port);
  /* Creates a new TCP socket and opens the socket in 'passive listening mode' (waiting for an 
  active connection setup request). The socket is bound to port number 'port' and to any 
  IP address of the PC. The number of pending connection setup requests is set to the 
  maximum. The newly created socket is return as the function result. This function is 
  typically called by a server. */
  
  
  Socket tcp_active_open(int remote_port, char *remote_ip );
  /* Creates a new TCP socket and opens a TCP connection to a socket on the PC with IP address 
  'remote_ip' on port 'remote_port'. The IP address that the host PC has to use to connect 
  to the remote PC, is not defined (it is left to the system to choose an available IP       interface). 
  The newly created socket is return as the function result. This function is typically 
  called by a client. */
  
  
  Socket tcp_wait_for_connection( Socket socket );
  /* Puts the socket 'socket' in a blocking waiting mode. The function will only return 
  when an incoming TCP connection setup request is received. The remote socket (the 
  remote IP address and port number) that initiated the connection request is returned 
  as the function result.  */
  
  
  void tcp_close( Socket *socket );
  /* The socket 'socket' is closed and any allocated resources are freed. */
  
  
  void tcp_send(Socket socket, void *buffer, int bufsize );
  /* The function initiates a send command on the socket 'socket'. Recall that the 
  send command might block. In total 'bufsize' bytes of data in 'buffer' will be send. 
  Of course, the socket 'socket' needs to be connected to a remote socket before this 
  function can be called.  */
  
  int tcp_receive (Socket socket, void* buffer, int bufsize);
  /* The function initiates a receive command on the socket 'socket'. Recall that the 
  receive command might block. Pending data in 'socket' will be copied to 'buffer'. The 
  function returns the number of bytes that were really copied to 'buffer', which might 
  be less than 'bufsize'. No more than 'bufsize' bytes however will be copied. Of course, 
  the socket 'socket' needs to be connected to a remote socket before this function can 
  be called.*/
  
  
  char * get_ip_addr( Socket socket );
  /* Returns the IP address to which the socket 'socket' is bound. The IP address is 
  returned as a string. */
  
  int get_port( Socket socket ); 
  /* Returns the port number to which the socket 'socket' is bound. */
  
  int get_socket_descriptor( Socket socket ); 
  /* Returns the socket descriptor to which the socket 'socket' is bound. */
  </code></pre>
  
  <p>The output that I get is like:</p>
  
  <pre><code>New message recieved.New message recieved.New message received....
  </code></pre>
  
  <p>Instead of:</p>
  
  <pre><code>New message received.
  Client disconnected.
  </code></pre>
  
  <p>It keeps saying that there is a new message, but there is none. This is very frustrating because in the actual gateway, the program is processing data that isn't there. Does anyone know how I can fix this?</p>
  
  <p>Thanks in advance.</p>