I’m currently working on a socket programming project. Let’s assume:
fd_set fd_in;
Now I would like to set the file Descriptor for the select function:
FD_SET(socket_fd, &fd_in);
Is that the right way ?
Then I use the select function:
int rc = select(socket_fd + 1, &fd_in, NULL, NULL, NULL);
Having done some research I haven’t managed to proceed.
The appropriate manual pages are available on line, for example here.
Nevertheless, it might not be clear to you that before adding any file descriptors to your fd_set
, you should first clear it:
FD_ZERO(&fd_in);
Then, yes, you use FD_SET()
just as you present in the question:
FD_SET(socket_fd, &fd_in);
That assumes that the value of socket_fd
is an open file descriptor.
Having done so, it is reasonable to use a pointer to the resulting fd_set
as one of the arguments to select()
, again as you present:
int rc = select(socket_fd + 1, &fd_in, NULL, NULL, NULL);
Do note that
that particular call registers interest only in the specified file descriptor becoming available for reading (or for accepting a connection if it is a listening socket), not for writing or exceptional conditions.
you must check select()
's return value and take appropriate action based on the result. Since you're using only a single fd_set
with a single element, without a timeout, you should expect select
to return either 1 (when the file descriptor is ready) or -1 (on error).
generally speaking, you need to set up the fd_set(s) each time you call select
. Except in certain special cases, the contents of the sets after select()
returns are often not the same as they were before the call, and in the event that select
reports an error then you cannot afterward rely on anything about them at all. Thus, when select()
is called in a loop, which is common, there generally needs to be fd_set setup code in the same loop.