meta data for this page
  •  

Connection multiplexing with select

The functions for accepting new connection (accept()) or receiving/sending (sendto(), recvfrom(), send(), recv()) will block the execution of the program until something is received. In order to multiplex different connections without blocking select() function can be used (or setting the sockets to non-blocking mode using fcntl()).

Using ''select()''

A basic approach.

#include <sys/select.h>
#define CL_MAX 50
 
int main(void) {
 
int running = 1;
int listensocket = -1;
int biggestsocket = 0;
 
/**
* Initialize the socket and do the binding here, with TCP remember to set to listening if it is a server socket
*/
 
fd_set incoming; // File descriptor set for select
struct timeval timeout; // Timeout struct for select (after successful completion the values in this can change!)
 
/** 
 * Set the timeout to one second, with value of 0.000000 it does not wait at all.
 * If given timeout struct is NULL select() will block until something happens.
 */
memset(&timeout,0,sizeof(timeout));
timeout.tv_usec = 0; // microseconds
timeout.tv_sec = 1; // seconds
 
while(running) {
  FD_ZERO(&incoming); // Clear the set of file descriptors
 
  // Add listening socket to the set and check if it is the biggest socket number
  FD_SET(listensocket,&incoming); 
  if(listensocket > biggestsocket) biggestsocket = listensocket;
 
  // Add standard input to the set and check if it is the biggest socket number
  FD_SET(fileno(stdin),&incoming); 
  if(fileno(stdin) > biggestsocket) biggestsocket = fileno(stdin);
 
  // Add all other sockets to the list
 
  // Use the biggestsocket+1 file descriptors with the incoming fd set with specified timeout for select
  switch(select(biggestsocket+1,&incoming,NULL,NULL,&timeout)) {
    case -1:
      // Error
      do_handle_select_error();
      break;
    case 0:
      // Select timeout
      break;
    default:
      // Some socket got something
 
      // Listening socket got a new connection
      if(FD_ISSET(listensocket,&incoming)) do_handle_listen_socket();
 
      // User gave some input
      if(FD_ISSET(fileno(stdin),&incoming)) do_handle_user_input();
  }
 
  // Check the timeout values for changes if needed...
 
}

CT30A5002 - Games and Networking