UNIX: Using select(…) with Multiple Sockets in C

If you’re having trouble with listening to multiple sockets (or file descriptors) in C in UNIX, then I’m going to save you a lot of time by posting some sample code. I found my answer in a discussion dating back to 1999.

Here is part of my original code:

for (i = 0; i < MAX_SOCKETS; i++) {
    FD_SET(sockets[i], &set);
}

while (1) {
    int returned = select(highfd + 1, &set, NULL, NULL, NULL);

    if (returned) {
        for (i = 0; i < MAX_SOCKETS; i++) {
            if (FD_ISSET(sockets[i], &set)) {
                int byteCount = recvfrom(sockets[i], (void*)&buffer, sizeof(buffer), 0, NULL, NULL);
                printf("%s", buffer);
            }
        }
    }
}

Now here's the code that works:

while (1) {
    for (i = 0; i < MAX_SOCKETS; i++) {
        FD_SET(sockets[i], &set);
    }

    int returned = select(highfd + 1, &set, NULL, NULL, NULL);

    if (returned) {
        for (i = 0; i < MAX_SOCKETS; i++) {
            if (FD_ISSET(sockets[i], &set)) {
                int byteCount = recvfrom(sockets[i], (void*)&buffer, sizeof(buffer), 0, NULL, NULL);
                printf("%s", buffer);
            }
        }
    }
}

Explanation

  • MAX_SOCKETS = Total number of file descriptors in the array sockets
  • sockets = An array containing file descriptors
  • highfd = The value of the highest file descriptor in the array. I believe that instead of highfd + 1 you could just pass in FD_SETSIZE

In the first code sample, I called FD_SET outside of the loop. Thus it was only being called once for each file descriptor. The problem with this was that the second time select(...) would get called, it would only listen to first file descriptor that was ready for reading. So even if the other file descriptors were ready for reading after the first iteration of the while loop, select(...) would ignore them. The fix was to call FD_SET on all file descriptors at every iteration of the loop.

When calling FD_SET on a file descriptor, that file descriptor is added to the set. Let's call this set my_set. You pass in my_set to select(...) which hangs until a file descriptor is ready for reading or until it times out. If one or more file descriptors are ready for reading, then select(...) will modify my_set, remove all file descriptors except the ones that were ready for reading. Pause. Read the previous sentence again a couple of times. Make sure you process it. The call to select(...) will modify my_set if one or more file descriptors are ready for reading and leave out the file descriptors that weren't ready for reading. So if you pass my_set again to select(...) you won't be passing in a set with all file descriptors you had originally intended to pass in. This is why you have to call FD_SET again for all file descriptors if you intend on calling select(...) more than once with the same set.

PS: The WordPress WYSIWYG editor sucks for posting code. Why can't it post code correctly out of the box? Why do I have to look around for an extension or for a fix? Tchuip... I turned the WYSIWYG editor off by running the following SQL UPDATE wp_usermeta SET meta_value = 'false' WHERE meta_key = 'rich_editing'

17 Responses to “UNIX: Using select(…) with Multiple Sockets in C”

  1. daniel pereira
    October 21st, 2008 | 6:42 pm

    thank yoU!! LOOL

  2. driedfruit
    February 10th, 2009 | 5:27 pm

    “Pause. Read the previous sentence again a couple of times. Make sure you process it.”

    Haha, thank you SO MUCH!

  3. Plano_TX
    February 25th, 2009 | 4:32 pm

    Thanks for the info. Saved me after 3 hr ordeal.

  4. December 9th, 2009 | 12:01 pm

    Aren’t you missing a call to FD_ZERO() before your FD_SET calls? Otherwise it seems like you’ll run out of slots in your “set” variable after a bunch of iterations through the loop

  5. Jonathan Provo
    June 2nd, 2011 | 4:47 pm

    I know this is an old blog, but thank you!

    My FD_SET() commands where outside of the loop, man pages don’t mention that.

  6. Fred
    March 18th, 2012 | 4:19 pm

    “Now here’s the code that works:” I actually loled. You know… the code doesn’t work. From the select man page:

    [...]
    RETURN VALUES
    Select() returns the number of ready descriptors that are contained in the descriptor sets, or -1 if an error occurred.[...]

    So “if(returned)” will still evaluate to true if -1 is returned, which is clearly an error.

    Cheers,
    Fred

  7. April 13th, 2013 | 7:13 am

    But there is a great article which I recommend to read.

  8. January 18th, 2015 | 7:33 am

    Hello admin do you need unlimited content for your blog ?
    What if you could copy post from other blogs, make
    it unique and publish on your blog – i know the right tool
    for you, just search in google:
    Ziakdra’s article tool

  9. December 17th, 2015 | 3:15 pm

    In reading your post I thgouht again of a paper I read that cited adults with autism. Reading about their experiences with those off the spectrum,’ I experienced a paradigm shift. I am now hyper-aware that we, as researchers of neurodevelopmental differences, must remember that the participants in our studies are different, not broken, and we should not devalue them by trying to fit them into a neuro typical mold.’ Labels can be a blinding as adjectives in many situations.

  10. April 28th, 2016 | 8:23 pm

    Con trai tôi đang theo học lập trình viên quốc tế tại Aptech bay gio chuyen sang hoc FPT Polytechnic có thuận lợi gì?

  11. May 10th, 2016 | 11:06 pm

    I blog quite often and I truly appreciate your content. Your article has truly peaked my interest.
    I’m going to bookmark your website and keep checking for new
    information about once a week. I opted in for your
    Feed as well.

  12. May 11th, 2016 | 9:06 pm

    She is the cutest! Great job making an authentic-looking Mary Poppins outfit! And hoe fun for your daughter.I am going to see the Theater production of Mary Poppins, and I’m making myself a Poppins-inspired outfit to wear to the show (and I’m an adult)!

  13. May 20th, 2016 | 9:00 am

    Calling all cars, calling all cars, we’re ready to make a deal.

  14. July 8th, 2016 | 9:19 am

    The flour to butter ratio in this recipe doesn’t make sense… that’s too much butter to have a “crumbly” mixture…. I made it and it was more like a batter.. regardless, it worked out.. I just had to sop up the excess grease with a paper towel after the crust baked. Next time I would make it with far less butter.

  15. August 1st, 2016 | 8:54 am

    IS Earthquakes happens in japan are the part of chain reaction of climate change is this any link between climate change and earthquakes because many times before earthquake its will show some miner changes in environment just like some different shades of temp extreme rise or fall in temp

  16. October 4th, 2016 | 2:09 pm

    I was going to comment on what a lovely card you made. It toally rocks! and then as I scroll down there is some yummy blog candy to….Total Bonas!!Thanks for sharing your talent and for a chance to win some blog goodness.

  17. October 22nd, 2016 | 10:35 am

    ostin myös itselleni tuota puhdistus ainetta jotain vuosi sitten,ja hyvin toimi puhdasta tuli joka kerta,kunnes erään kerran näyttöni oli todella likainen,ja jouduin suihkuttamaan sitä aineella useaan kertaan,no kuinkas sitten kävikään aine imeytyi ilmeisesti näytön reunojen läpi sisäpuolelle,josta on jäänyt muistoksi näyttöön valkoinen laikku onneksi aine suurimmaksi osaksi haihtui mutta merkit aineen käytöstä jäivät:Niin että kannattaa käyttää tuota puhdistus ainetta varovaisesti

Leave a reply