select() 最大的套接字数量

6

更多关于异步编程的内容!

好的,我现在已经有一个可以正常工作的异步套接字程序用于我的主要聊天应用程序,它运行得非常顺畅!但是我有一个问题..

使用select()时,每个集合中可以使用的文件描述符的最大数量是多少?我读到了1024的限制...

如果这个限制确实是硬编码的,我不能将FD_SETSIZE限制得更高,那么一旦达到该限制,我应该生成另一个线程吗?还是其他什么方法?这真的是一个问题吗?


好的,如果我想要使用轮询,听起来像是我只能使用*nix操作系统了? - ultifinitus
Windows有WSAPoll(),它的工作方式与poll()非常相似。 - Jeremy Friesner
4个回答

11

是的,FD_SETSIZE 有一个限制,为1024。您可以通过查看select.h头文件来轻松检查这一点。人们尝试增加这个限制,但报告从“可工作”到“一段时间后崩溃”不等。如果您需要那么多连接,请使用poll代替。

阅读的一篇非常好的文章。


谢谢你的文章!还有答案! - ultifinitus

3

如果您在一个符合Posix标准的系统下编程,您应该能够使用poll()函数代替select()函数,这样就可以消除您提到的限制。或者,您可以连续多次调用select()函数,但一定要使用相对较短的超时时间。


使用多次select()是行不通的,因为限制在于大于FD_SETSIZE的FD。也就是说,一旦使用大于1024的fd,它就会中断。请仔细阅读man页面上的注释部分。 - Milan
如果您为新的句柄集重新构建集合,或者使用完全不同的集合,它将起作用。我已经在Windows下完成了这个操作。 - Jon Trauntvein
对于我的测试系统,那实际上就是我最终采取的方法。我正在考虑为每个1024的倍数简单地生成新线程。 - ultifinitus
@JonTrauntvein 如果我没记错的话,在Windows上,FD_SETSIZE是可以放在集合中的套接字数量,但在Linux上,它是集合中可以有的最大套接字号码(加一)。因此,如果FD_SETSIZE为1024,并且您有1025个套接字,则其中一个将被编号为1025,您无法使用它。(大约) - user253751

3
对于大量的套接字,可以考虑使用像libevent这样的库。
该库可以抽象出几个特定于操作系统的高级功能,如/dev/poll、kqueue、epoll和事件端口。使用这些功能,您可以处理大量连接。

刚刚看了一下,我会试试看! - ultifinitus

1

您没有说明您使用的操作系统,但对于大多数操作系统而言,如果您想要在使用select时使用大于1024的文件描述符,您可以在包含sys/socket.h之前将#define FD_SETSIZE定义为更大的数字。不幸的是,这在Linux上不起作用。


我曾经读到过这方面的内容,不幸的是服务器可能在多个操作系统上运行。 - ultifinitus

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