4

我认为select()fd_set中的 NFDS 决定了该函数将在 READFDS 和其他s中检查多少个套接字。因此,如果我们在 中设置 3 个套接字fd_set,但我只想检查第一个,我必须调用 select(1 + 1,...)。这是正确的吗?

或者“ nfds 是三个集合中任何一个中编号最高的文件描述符,加上 1 ”在linux select man中是否意味着不同的东西?另外为什么我们需要加+1?

示例代码 - 已修复

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);
...
4

3 回答 3

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

你的代码是错误的。您不需要传递监视的文件描述符的数量。您需要选择您感兴趣的最大描述符并添加 1。

标准说:

nfds 参数指定要测试的描述符范围。应在每组中检查第一个 nfds 描述符;也就是说,应检查描述符集中从零到 nfds-1的描述符

所以这只是select:的预期语义,nfds不是文件描述符的数量(正如它的名字所暗示的那样),而是监视范围的上限。

引用中的粗体部分还解释了为什么需要将 1 添加到nfds.

于 2012-08-19T08:09:57.543 回答
6

" nfds 是三组中编号最高的文件描述符,加 1 "

每个文件描述符都由一个整数值表示。因此,他们不是在要求x-th您要检查的描述符,而是在要求您的+1中描述符的最高整数值。READFDS

顺便说一句,你应该检查poll(2)ppoll(2)

于 2012-08-19T08:10:51.687 回答
4

基本上,您放入 FD_SET() 和类似调用的“fd”是整数。select 所需的“nfds”是所有这些值的 max() 加上 1。

于 2012-08-19T08:10:43.870 回答