gpt4 book ai didi

c++ - 超过 1024 个客户端使用 fd_set?

转载 作者:行者123 更新时间:2023-11-28 04:47:18 25 4
gpt4 key购买 nike

我正在使用 select() 来衡量服务器没有收到任何新消息的时间。代码非常简单,看起来像这样:

int res = -1;
do {
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
res = select(maxfd+1, &readfds, NULL, NULL, &tv);
gettimeofday(&current, NULL);
if (get_time_diff(current, last) >= diff) {
// do something
}
} while (res <= 0);

当然,这不适用于超过 1024 个连接,因为 fd_set 只有 1024 位。幸运的是,我不需要存储所有的 FD,我只需要知道新连接何时发生。所以我将 maxfd+1 替换为服务器 FD 之后的下一个数字(始终相同,在我的例子中等于 18)。

现在一切似乎都很好,所有客户端都从服务器收到正确的消息。但是,我不确定它是否是一个有效的解决方案,而且它肯定不是一个非常干净的解决方案。这会导致任何我不知道的问题吗?

最佳答案

是的,select 受设计限制,使用 fd 值超过 1023 是不安全的。

老实说,您可能找不到使用 select 的重负载生产服务器(如果您这样做,那么您可能不应该使用它们)。

So I replaced maxfd+1 with the next number after the server's FD (which is always the same and in my case equals 18).

我假设你的例子是一个最小的例子,你不只是在寻找一个单一的倾听fd(否则,你可能只会阻止接受 ,这更有意义)。

这将提醒您另一个文件描述符已打开*...但是,我觉得这不是最佳方法,因为:

  • 它只会对第一个文件描述符这样做...

    新客户端将根据第一个客户端的状态行事,他们自己的状态将被忽略,因为他们的 fd 的状态从未被测试过。

  • 它使您的代码既脆弱又僵硬。

  • 其他文件描述符(非套接字)可能会占用特定的文件描述符,从而使实现完全崩溃。

  • 如果将文件描述符添加到集合中,您仍然需要测试它们的值。

更好的解决方案可能包括:

  • 测试客户端的 fd 值并强制限制 (if (fd >= 1024) close(fd))。

  • 使用 poll(老实说,这就是它存在的原因 - 它的引入是为了解决 select 施加的限制)。

  • 使用操作系统特定的 API(epoll 用于 Linux,kqueue 用于 BSD/macOS 等)。

  • 使用抽象出操作系统特定 API 的库(例如,libev)。

祝你好运!


* Unix 风格的系统保证任何新的文件描述符都将被分配到可用的最低 fd 值。

这意味着您的第一个客户端将始终收到服务器 + 1(假设您没有打开或关闭任何其他文件描述符)。

但是较新的文件描述符将被分配更高的值(除非有更小的文件描述符可用)。因此,当您测试第一个客户端的状态时,永远不会轮询其他客户端。

关于c++ - 超过 1024 个客户端使用 fd_set?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49021919/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com