如何确定select的最大fd?

就像标题一样简单,我希望得到最高的fd数作为第一个参数传递,但是使用FD_SETSISE似乎是如此低效和不必要。 我的假设是,在我的进程开始之后,创建的最新套接字将始终具有最高的fd编号,因此我可以简单地向其添加1并将其传递给select ,这是真的吗?

FD_SETSIZE效率低下。 对于集合中允许的最大数量的描述符,它只是一个便利宏。 如果您使用它,select将搜索整个集合,即使您实际使用的最高描述符可能非常低。 也就是说,如果要传递给select的最高描述符是7,则从8到1024(或者在您的平台上等于任何FD_SETSIZE)没有任何意义。

我的假设是,在我的进程开始后,创建的最新套接字将始终具有最高的fd编号

不,这是错的。 操作系统在打开文件或套接字时将选择最低的可用文件描述符。 因此,如果在程序过程中如果打开0-7,关闭5,然后创建另一个套接字,则将分配5。

最重要的是你必须自己跟踪最高的开放式sockets。 作为一种做法,因为你必须在每次选择调用之前使用FD_SET想要在select中使用的集合,所以在那里放置一个小的if语句以找到你要添加到集合中的最大文件描述符并不困难。 它不需要太多涉及这样的东西:

  int maxfd; for (i = 0, maxfd = 0; i < nclients; i++) { FD_SET(clients[i], &read_fds); if (clients[i] > maxfd) maxfd = clients[i]; } select(maxfd + 1, ........); 

替代方案是pollepoll ,消除一些选择的麻烦。