处理超过1024个套接字

Handling more than 1024 sockets?

本文关键字:套接字 1024个 处理      更新时间:2023-10-16

我正在处理一个MMO游戏服务器项目,遇到了一个问题。这是select()方法的限制。我想用一个线程处理1024个以上的套接字I/O。我想用单线程来实现这一点,因为我已经尝试过制作一个多线程处理系统。该系统创建了3个线程(例如,在4核处理器中;1是main,3是select()处理程序)来处理select()方法,但又出现了另一个问题,现在我们的限制达到了3072(1024*3),这不是解决方案!在这个想法之后,我想制作一个无阻塞的套接字系统,使用这个系统,我在一个单独的线程中调用了两个不同的选择方法,如下所示;"select()select()"。它们按顺序返回,我可以按顺序处理它们。但我认为还有另一个问题。如果我想实现像"while(true){select()select()}"这样的线程和select()方法(非阻塞)重新运行,我会像一个空的"which(true)"块一样重载CPU。如果我想让select()超时,我无法实时处理底部的select()。现在我无法为它制定算法。有人能帮我吗?

注意:我不想使用poll-epoll wsapoll等。(poll无法处理微秒,它不如select快!)和类似libevent的第三方库(我想自己制作!)

最终解决方案(我认为):我不需要为I/O操作处理纳秒,因为处理它没有意义。轮询是处理1024个以上套接字I/O的好方法。我会研究一些东西来理解MMO系统。最后一个问题是,我会做一些测试,在问问题之前我会尝试一下:)谢谢!

编辑:我是本问答的新手;一个平台。你能告诉我我的问题出了什么问题吗

使用select对如此多(数千)的连接来说是根本错误的。虽然select通常在只有极少数(可能是几十个)套接字时速度更快,但它的扩展范围非常大,甚至可以达到几千个。据我所知,无论在哪里,select都会随着连接数量的增加而线性下降(甚至比这更糟,但我不会详细介绍。)

即使是poll在扩展到数千个连接方面也不会比select做得更好。它对可以轮询的文件描述符数量没有select的(低)限制,但它仍然会随着连接数量线性扩展。

您真正应该使用的是特定于平台的设施,如epollkqueue。它们的伸缩性非常好(通常O(1)),但显然它们不可移植。

我认真建议您考虑像libev这样的东西,它是一个可移植的、经过高度测试的、围绕特定平台的设施和服务的精简包装器。

这是因为特定于平台的方法(例如selectpollepollkqueue、I/O完成端口、事件端口等)彼此不同,并且它们在一个或两个以上的平台上都不可用,或者它们的限制和行为细节略有不同。这些功能甚至可能从操作系统的一个版本更改到下一个版本(例如Linux 2.6.9上的epoll,IIRC。)

即使您不关心代码的可移植性或未来性,这样的库也可以为您提供更多的功能和更好的界面。

您可以尝试的另外两个库是libevent(稍微大一点,速度慢一点,但功能更多)和libuv

考虑到您设置的要求,您的问题没有解决方案。

  • 克服select()FD_SETSIZZE(1024)文件描述符限制的正常方法是使用poll()(或者更好的替代品epoll和kqueue),但您拒绝了该选项
  • 否则,您总是可以通过在具有不同文件描述符集的不同线程中并行调用select()多次来克服这个问题。。。但你也拒绝了这个选择

我不相信真的有任何其他的解决方案!

也许您应该解释为什么poll()等选项和线程选项都不合适。你的要求似乎是没有正当理由的人为限制。