选择(select)和for循环范围(range)读取套接字(socket)的问题

3

关于使用 select() 的快速问题。

我正在使用 select() 从多个套接字中读取数据。当我查找如何使用 select() 的示例时,许多教程都展示了通过 for 循环并使用 FD_ISSET 检查的方法。我对这些教程的问题在于 for 循环是从 i = 0 开始的,并检查文件描述符 i 是否已设置位。那么 for 循环不能从您的 minfd 开始吗(就像您会跟踪 maxfd 一样)?或者我错过了什么?

以下链接是这样一个 for 循环的示例(查看他给出的第四个示例) http://www.developerweb.net/forum/showthread.php?t=2933

如果这是唯一一个使用这种 for 循环的示例,我可能会理解它是错误或糟糕的编码,但我已经看到了几个类似的 for 循环示例,无用地遍历成千上万的套接字,我相信我错过了什么。欢迎任何评论或意见。

2个回答

3

有几种可能的原因:

  • 如果你知道你总是在监视文件描述符列表中包括stdin,那么你就知道minfd始终为0,所以特别跟踪它没有意义;
  • 新的文件描述符总是按最低可用编号分配 - 因此,除非您的应用程序行为非常不寻常,否则minfd通常会接近零。

与其直接循环遍历文件描述符,更常见的做法是循环遍历包含文件描述符(以及一些元数据)的某些数据结构 - 例如,如果您将未完成的连接保留在链表中:

for (conn = list_head; conn; conn = conn->next)
{
    if (FD_ISSET(conn->fd, &readfds))
    {
        /* Do something ... */
    }
}

1
换句话说,您需要将文件描述符存储在某个地方,然后迭代并检查数据是否可用。我猜示例仅显示简单的for循环迭代到maxfd的原因是这是最简单的方法,而不必涉及特定实现数据结构以存储文件描述符。 - stefanB

0

我想你可以跟踪实际的文件描述符,并仅检查那些你知道已添加到集合中的描述符。

文件系统重用最小可用文件描述符,进程可以访问的文件描述符数量始终有限,因此我猜maxfd数字不会太大。

另一个猜测是,因为它是用C编写的,这是实现迭代所有文件描述符集的最简单方法。

在C++中,您可以轻松创建文件描述符列表或向量,但在C中,您必须添加更多关于跟踪文件描述符的说明,所以为了保持简单,他们只使用maxfd作为上限。

以上是我的个人意见。


我正在使用UNIX编程,人们说在UNIX中一切皆为文件。因此我认为有很多文件描述符需要计数(即使它不需要太长时间,也是资源的浪费)。感谢您的建议。 - Fantastic Fourier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接