我正在开发一个多协议套接字服务器,在我第一次尝试时,我把它作为事件驱动,因为这是我所知道的最好的方式,但是通过使用这种方法,我无法找到一种有效的方式来链接特定于应用程序的数据对于套接字,所以每次事件我都必须执行搜索才能将套接字链接到它的上下文。经过一些研究后,我发现IO完成端口是一种更好的工作方式,因此经过大量阅读后,我终于能够重新编写代码,以便在IOCP方法下工作。
然而经过一些进一步的研究后,我发现这个article(请阅读:“接受连接”)建议通过在另一个线程上处理FD_ACCEPT事件来将接受操作与I / O进程分离,他也是建议将此作为防止恶意攻击的手段...解释确实有意义,但作者没有考虑到在这种方法下没有办法(至少AFAIK)将套接字与其上下文数据链接,因此应用在服务器上的这个建议,它监听绑定到多个地址的多个端口,每个端口处理不同的协议,必然涉及每个FD_ACCEPT事件的搜索操作,这可能(或可能不)打败解除接受的原始建议......和这就是我首先迁移到完成端口的原因。
所以..我想知道是否有2个完成端口,一个用于接受操作,一个用于I / O过程可以被认为是一般的热门操作,但特别是关于性能...或者最好有只有一个?
更新
经过一些实验,我发现,通过使用2个IOCP(在分离的线程上)将接受过程与I / O过程分离是根本不可行的,并且由于这个事实,不能获得效率提升。因此,即使他没有明确提及它,作者也是正确的,解耦这两个过程的唯一可行方法是通过处理FD_ACCEPT事件所有暗示,但如果他在他的陈述中也是正确的,那么唯一在我的情况下使其可行的方法是找到一种有效的方法将每个套接字链接到其上下文数据,或者换句话说;无需搜索,所以原始问题仍然存在。
答案 0 :(得分:5)
如果您正在使用IOCP进行数据流,那么通常最好使用IOCP来接受新连接,因此使用AcceptEx()
是一个好主意。不要费心去处理使用它来读取来自对等端的第一块数据的复杂性,很难避免这种打开的潜在拒绝服务攻击,并且大多数服务器设计的性能提升可以忽略不计。只需将它作为重叠的Accept使用,这样可以节省每个端口必须有一个单独的接受线程,因此非常好地扩展。
就我个人而言,我从未使用过您所链接文章的FD_ACCEPT
想法。只需在完成后发布新的AcceptEx
并在开始时发布可配置的号码。这样你就会有'X'等待接受。
我有一些文章和示例代码here可能有所帮助。