c++ - IO完成端口中的业务逻辑

标签 c++ winsock2 asyncsocket overlapped-io io-completion-ports

我对winsock2中的IO Completion Port和AcceptEx有一些疑问

如有错误,请指正。

  1. AcceptEx 是一种接受请求或连接的重叠方式。然而,正如本网站上的多个帖子所指出的,如果 AcceptEx 需要数据但连接的客户端未发送数据,则 AcceptEx 很容易受到 DOS 攻击。那么,只要在dwReceiveDataLength中输入0就可以解决这个问题吗?

  2. 此外,在接受相应连接时能够从客户端接收数据而不是稍后使用 AcceptEx 接收数据有什么优势?

  3. 接受来自对端端点的连接并将其与 IO 完成端口关联后,请求将作为与其各自句柄关联的完成数据包在 IO 完成端口中排队。阻塞在完成端口上的工作线程将根据 NumberOfConcurrentThreads 被唤醒以服务请求。那么,完成端口中的线程是IO线程吗?

  4. 那么,我应该在套接字服务器中哪里实现业务逻辑或操作呢?例如,来自客户端的请求将数字发送到服务器进行处理,而服务器就像计算器一样通过回显计算的输出进行响应。那么这个逻辑可以在IO Completion Port中实现吗?

  5. 如果逻辑在 IO 完成端口中实现(当 IO 完成端口中处于事件状态的 IO 线程(假设)正在执行 WSARecv WSASend)),如果积压全部取完,IO 线程会在等待计算完成时阻塞,导致无法接受任何连接吗?

编辑:

  • 例如,接受客户端套接字并在 IO 完成端口 (main_cpl_port) 中排队/关联后,在此 main_cpl_port 上阻塞的线程调用GetQueuedCompletionStatus将完​​成数据包出队,然后将数据读入分配的缓冲区。在将任何响应写回客户端之前,将处理/解析缓冲区中的“命令”(例如:GoToCalculator、GoToRecorder)。
  • 例如,GoToCalculator 负责其他计算相关命令。
  • 在这种情况下,GoToCalculator实际上是另一个IO完成端口,它满足所有与计算相关的请求。假设完成端口被命名为calc_completion_port
  • 因此,是否有可能将来自 main_cpl_port 的完成数据包发布到 calc_completion_port 以供将来的 IO (发送和接收)来自当前与 main_cpl_port 关联的客户端套接字。这是 PostQueuedCompletionStatus 的用途吗?
  • 发布到 calc_completion_port 后从客户端发送的消息是否可以被阻塞在该完成端口上的线程接收? 换句话说,如何将连接从另一个端口重定向到其他完成端口?

最佳答案

1) 避免潜在的 AcceptEx DOS 攻击很容易,只需不提供任何数据空间,一旦建立连接,AcceptEx 就会完成。

2) 使用 AcceptEx 意味着您不需要单独的线程来运行接受循环。这会从系统中删除一个线程并减少上下文切换。如果您正在监听多个套接字(不同的端口/接口(interface)),这尤其有用,因为每个监听套接字都需要自己的接受线程。

3) 是的,在 IOCP 上调用 GetQueuedCompletionStatus 的工作线程可以被视为 I/O 线程...

4)这取决于。我构建了具有不同的、固定大小的 I/O 线程池的系统,这些线程池从不执行任何阻塞操作,并且设计了单独的扩展线程池来执行阻塞操作。这个想法是,这将防止所有线程被阻塞并阻止 I/O...这要求您将工作项传递给另一个线程池,这会导致不必要的上下文切换和复杂性,但这意味着您始终拥有线程执行 I/O 操作(例如在 AcceptEx 完成时处理新连接)...当 IOCP API 用于取消挂起操作(如果发出的线程在操作完成之前退出)时,这种设计可以很好地工作。既然操作系统已经改变了规则并且挂起的操作没有被取消,那么没有真正的理由为什么你不只是拥有一个扩展/收缩的 I/O 线程池并在那里完成你的所有工作......你只需要跟踪如何许多线程可用,并在您需要扩展/收缩池时创建/销毁线程...

5) 参见 4。

关于c++ - IO完成端口中的业务逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35909741/

相关文章:

c++ - 取消阻塞套接字的连接?

C# 套接字开始接受与选择?

c - Windows 线程接受套接字上的连接

windows - 在 IOCP 客户端应用程序中添加 OpenSSL 支持

c - 套接字的 FIONBIO 和 FIOASYNC 有什么区别?

c - 如何安装xsock?

c++ - 如何使用模板编程创建多类型数组

android - 为什么双簧管中名为 OboeSinePlayer 的示例代码在 Android 上一直停止?

c++ - CYGWIN 求助

c++ - Const 正确性和 shared_ptr 转换