Search code examples
c++cfile-descriptorposix-select

How to iterate through a fd_set


I'm wondering if there's an easy way to iterate through a fd_set? The reason I want to do this is to not having to loop through all connected sockets, since select() alters these fd_sets to only include the ones I'm interested about. I also know that using an implementation of a type that is not meant to be directly accessed is generally a bad idea since it may vary across different systems. However, I need some way to do this, and I'm running out of ideas. So, my question is:

How do I iterate through an fd_set? If this is a really bad practice, are there any other ways to solve my "problem" except from looping through all connected sockets?


Solution

  • Select sets the bit corresponding to the file descriptor in the set, so, you need-not iterate through all the fds if you are interested in only a few (and can ignore others) just test only those file-descriptors for which you are interested.

    if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
       perror("select");
       exit(4);
    }
    
    if(FD_ISSET(fd0, &read_fds))
    {
       //do things
    }
    
    if(FD_ISSET(fd1, &read_fds))
    {
       //do more things
    }
    

    EDIT
    Here is the fd_set struct:

    typedef struct fd_set {
            u_int   fd_count;               /* how many are SET? */
            SOCKET  fd_array[FD_SETSIZE];   /* an array of SOCKETs */
    } fd_set;
    

    Where, fd_count is the number of sockets set (so, you can add an optimization using this) and fd_array is a bit-vector (of the size FD_SETSIZE * sizeof(int) which is machine dependent). In my machine, it is 64 * 64 = 4096.

    So, your question is essentially: what is the most efficient way to find the bit positions of 1s in a bit-vector (of size around 4096 bits)?

    I want to clear one thing here:
    "looping through all the connected sockets" doesn't mean that you are actually reading/doing stuff to a connection. FD_ISSET() only checks weather the bit in the fd_set positioned at the connection's assigned file_descriptor number is set or not. If efficiency is your aim, then isn't this the most efficient? using heuristics?

    Please tell us what's wrong with this method, and what are you trying to achieve using the alternate method.