【发布时间】:2014-05-07 08:50:25
【问题描述】:
我正在使用 select 来处理 udp 服务器上的连接。如果我在一段时间内没有收到数据包,我想超时。问题是,似乎我可以正确超时并且只从一个客户端读取,或者从所有客户端读取而不超时。
此功能的不同之处在于选择的第一个参数int nfds
这是我的代码:
int TIMEOUT = 5;
for (;;) {
FD_ZERO(&read_handles);
FD_SET(udpFD, &read_handles);
timeout.tv_sec = TIMEOUT;
timeout.tv_usec = 0;
if (select(udpFD+1, &read_handles, NULL, NULL, &timeout) == 0) {
printf("Select has timed out...\n");
return 1;
} else {
int length = 1;
if (FD_ISSET(udpFD, &read_handles)) {
//process read.
}
}
}
此版本不会超时。如果我将选择行更改为:
if(select(udpFD, &read_handles, NULL, NULL, &timeout) == 0)
它确实超时,但它只接收来自我的一个客户的数据。
udpFD 是我正在查看的唯一句柄,但它的值为 4,因为它不是我创建的第一个描述符。我不知道这是否有区别,因为它是最大值。
如何同时超时并从我的两个客户端获取数据?
【问题讨论】:
-
“不超时”到底是什么意思?你的意思是它永远留在
select? -
select也会在发生错误时返回(-1),而您并未对其进行测试。如果是这种情况,FD_ISSET 将返回(0)是理所当然的。 5 秒是很长的时间 - 如果EINTR/EAGAIN是罪魁祸首,我不会感到惊讶。 -
@DavidSchwartz 是的,它会永远留在
select。 -
@BrettHale 我现在只向它发送两条消息。它也具有相同的行为,但超时时间更短。我不知道这是否会改变问题,但我会检查错误代码,看看是否有影响。
-
@publ1c_stat1c 您是否通过在
select之前和之后记录某些内容来100% 确认这一点?