我对IO完成端口以及winsock2中的AcceptEx有疑问
如果我错了,请纠正我。
AcceptEx是一种接受请求或连接的重叠方式。但是,正如本网站上的多个帖子所指出的,AcceptEx
如果AcceptEx期待数据但不是由连接的客户端发送,则容易发生DOS攻击。那么,只需将0添加到dwReceiveDataLength
?
此外,在接受相应连接时能够从客户端接收数据而不是稍后使用AcceptEx
接收数据有什么好处?
接受来自对端端点的连接并将其与IO完成端口关联后,请求将在IO完成端口中排队,作为与其各自句柄关联的完成数据包。阻塞在完成端口上的工作线程将被唤醒,具体取决于NumberOfConcurrentThreads
以提供请求。那么,完成端口中的线程是 IO线程吗?
那么,我应该在哪里实现套接字服务器中的业务逻辑或操作?例如,客户端发送数字到服务器进行处理的请求,而服务器就像计算器一样,通过回显计算的输出来响应。因此,这个逻辑可以在IO完成端口中实现吗?
如果逻辑在IO完成端口中实现(当 IO线程(假设)在IO完成端口中处于活动状态时执行WSARecv
或WSASend
) ), IO线程会在等待计算完成时阻塞,因此如果积压全部都没有接受连接吗?
编辑:
GetQueuedCompletionStatus
使完成数据包出列,然后将数据读入已分配的缓冲区。在将任何响应写回客户端之前,缓冲区将被处理/解析为“command”(例如:GoToCalculator,GoToRecorder)。PostQueuedCompletionStatus
用于什么?答案 0 :(得分:3)
1)避免潜在的AcceptEx DOS攻击很容易,只是没有为数据提供任何空间,一旦建立连接,AcceptEx就会完成。
2)使用AcceptEx意味着您不需要单独的线程来运行接受循环。这将从系统中删除一个线程并减少上下文切换。如果您正在侦听多个套接字(不同的端口/接口),这尤其有用,因为每个侦听套接字都需要自己的接受线程。
3)是的,在IOCP上调用GetQueuedCompletionStatus的工作线程可以被认为是I / O线程......
4)这取决于。我构建了具有不同的,固定大小的I / O线程池的系统,它们从不执行任何阻塞操作和单独的扩展线程池,旨在执行阻塞操作。这个想法是这会阻止所有线程被阻塞并阻止I / O ......这要求你将工作项传递给另一个线程池,这会导致不必要的上下文切换和复杂性,但这意味着你总是有线程执行I / O操作(例如在AcceptEx完成时处理新连接)...当IOCP API用于取消挂起操作时,如果在操作完成之前发出的线程退出,则这种设计过去很好。既然操作系统已经改变了规则并且暂停操作没有被取消,那么你没有真正的原因就是不要只有一个扩展/收缩的I / O线程池来完成你所有的工作......您只需要跟踪可用的线程数,并在需要扩展/收缩池时创建/销毁线程......
5)见4。