【发布时间】:2018-02-28 14:39:16
【问题描述】:
我使用select() 来衡量服务器没有收到任何新消息的时间。代码很简单,看起来像这样:
int res = -1;
do {
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
res = select(maxfd+1, &readfds, NULL, NULL, &tv);
gettimeofday(¤t, NULL);
if (get_time_diff(current, last) >= diff) {
// do something
}
} while (res <= 0);
当然,这不适用于超过 1024 个连接,因为fd_set 只有 1024 位。幸运的是,我不需要存储所有的 FD,我只需要知道何时发生新连接。所以我用服务器 FD 之后的下一个数字替换了maxfd+1(它总是相同的,在我的情况下等于 18)。
现在一切似乎都很好,所有客户端都从服务器收到了正确的消息。但是,我不确定它是否是一个有效的解决方案,而且它肯定不是一个非常干净的解决方案。这会导致我不知道的任何问题吗?
【问题讨论】:
-
您是否建议接受套接字上的活动将唤醒仅对侦听套接字敏感的
select调用?这绝对不是一个安全的假设。select()几乎已经失宠,更好的选择是poll(便携式)和epoll(Linux)或完成端口(Windows)。 -
@BenVoigt 当然,没有任何活动,但我认为如果连接是新的,它应该可以工作。在我的应用程序中,每个客户端只连接一次并发送一条消息(总是),所以我想我可以做出这个假设。好像对监听socket加一个新socket比较敏感。
-
是的,这很好,尽管在 TCP 中,数据通常与用于三次握手的数据报是分开的......然后如果你只是
select()-ing 在侦听套接字上,您最终可能会卡在新连接上的同步recv()中,同时无法处理其他连接尝试。有一个接受队列,所以你不会失去客户,但它可能会打乱时间。 (以及连接然后发送零消息的恶意客户端......) -
您确定问题应该标记为
c++吗?对我来说看起来像c... -
@Myst:这是很好的 C++ 代码。