IO完成端口中的业务逻辑

Business logic in IO completion Port

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

如有错误请指正

  1. AcceptEx是一种接受请求或连接的重叠方式。但是,正如该站点上的多个帖子所指出的那样,如果 AcceptEx 需要数据但连接的客户端未发送数据,AcceptEx 很容易受到 DOS 攻击。那么,是否可以通过在dwReceiveDataLength?

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

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

  5. 那么,我应该在socket服务器的什么地方实现业务逻辑或者操作呢?例如,来自客户端的请求将数字发送到服务器进行处理,而服务器则像计算器一样通过回显计算输出进行响应。那么这个逻辑是否可以在IO Completion Port中实现呢?

  6. 如果在IO完成端口中实现逻辑(当IO完成端口中活跃的IO线程(假设)正在执行WSARecvWSASend)), IO threads 是否会在等待计算完成时阻塞从而导致如果积压全部被占用则无法接受任何连接?

已编辑:

1) 避免潜在的 AcceptEx DOS 攻击很容易,只要不提供任何 space 数据,AcceptEx 将在连接建立后立即完成。

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

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

4) 这取决于。我已经构建了具有不同的、固定大小的 I/O 线程池的系统,这些线程池从不执行任何阻塞操作,并分离扩展线程池来执行阻塞操作。这个想法是这样可以防止所有线程被阻塞并防止I/O ...这需要您将工作项传递给另一个线程池并且它会导致不必要的上下文切换和复杂性但这意味着您总是有线程执行 I/O 操作(例如在 AcceptEx 完成时处理新连接)...当 IOCP API 用于取消未决操作时,如果发出的线程在操作完成。既然 OS 已经改变了规则并且挂起的操作没有被取消,那么没有真正的理由为什么你不只是有一个 expanding/contracting 线程池 I/O 并在那里完成你的所有工作。 .. 您只需要跟踪有多少可用线程和 create/destroy 个线程,因为您需要 expand/contract 您的池...

5) 见 4.