Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select from multiply sockets - right NFDS value?

Tags:

c

linux

sockets

I think that NFDS in select() determines how many sockets the function will check in READFDS and the other fd_sets. So if we set 3 sockets in our fd_set, but I want to check only first one, I have to call select(1 + 1,...). Is this right?

Or does "nfds is the highest-numbered file descriptor in any of the three sets, plus 1" in linux select man means something different? Also why do we need to add + 1?

Example code - fixed

int CLIENTS[max_clients];//Clients sockets

int to_read;
FD_ZERO(&to_read);

int i;
int max_socket_fd = 0;

for (i = 0 ; i < max_clients ; i++)
{
 if(CLIENTS[i] < 0)
    continue;

 int client_socket = CLIENTS[i];
 if(client_socket > max_socket_fd)
    max_socket_fd = client_socket;
 FD_SET(client_socket , &to_read);
}

struct timeval wait;

wait.tv_sec = 0;
wait.tv_usec = 1000;

int select_ret = select(max_socket_fd + 1, &read_flags, NULL, NULL, &wait);
...
like image 651
Aristarhys Avatar asked Dec 03 '22 02:12

Aristarhys


1 Answers

int select_ret = select(current_clients + 1, &read_flags, NULL, NULL, &wait);

Your code is wrong. You don't need to pass the number of file descriptors monitored. You need to pick the biggest descriptor you're interested in and add 1.

The standard says:

The nfds argument specifies the range of descriptors to be tested. The first nfds descriptors shall be checked in each set; that is, the descriptors from zero through nfds-1 in the descriptor sets shall be examined

So it's just the expected semantics of select: nfds is not the number of file descriptors (as its name would imply) but rather the upper limit of the watched range.

The bold part in the quote also explains why you need to add 1 to your nfds.

like image 71
cnicutar Avatar answered Dec 11 '22 13:12

cnicutar