使用sockets时,哪些IO操作会导致完成包发送到完成端口?

What IO operations causes completion packets to be sent to the completion port when using sockets?

在IOCP中,当开始一个IO操作时,比如WSARecv(),当IO操作完成时,会向完成端口发送一个完成包。

我想知道的是在使用socket的时候是什么IO操作导致完成包被发送到完成端口,比如我知道WSASend()WSARecv()AcceptEx(),并且 PostQueuedCompletionStatus() 导致发送完成数据包。还有其他 IO 操作吗?

你没抓住重点。导致发送完成数据包的是 事件, 而不是 API 调用。基本上只有几个TCP事件:

  • 入站连接
  • 出站连接完成
  • 数据
  • 写完
  • 超时
  • 流结束,
  • 错误。

仅当以请求完成排队的方式调用可以生成完成的 API 调用时,才会将完成排队到与套接字关联的 IOCP。因此,通过阅读文档并将 OVERLAPPED 结构传递给它们,您将知道哪些 API 调用可以生成补全。

因此,您真的不需要知道问题的答案,因为您永远不会得到您不希望得到的结果,因为您必须使用适当的参数调用适当的 API要生成的完成。

然后,您可以通过在 OVERLAPPED 中添加某种形式的识别 "per operation data" 来区分导致生成完成的 API,或者通过 'extended overlapped stucture'或者使用事件句柄作为不透明数据。无论哪种方式,您都有机会从 API 调用站点向 IOCP 完成处理站点发送一些上下文。此上下文是您自己设计的,可以告诉您启动完成的原因。

然后您可以使用 GetQueuedCompletionStatus() 调用中的 return 值来确定完成是成功还是失败,然后您可以使用 [=13= 访问失败的错误代码](尽管 see this answer 了解更多有关附加环的详细信息,您可以跳过该环以获得更准确的错误代码)。

这样您就可以确定您拥有 EJP 答案中列出的哪些事件。

可以为套接字操作生成完成的实际函数集会随着 OS 中的变化而变化。确定这些适用于您所针对的操作系统的最简单方法是阅读 MSDN 文档或搜索 SDK headers for lpOverlapped... 正如您将看到的从当前的 VS2013 headers 来看,有不少与套接字相关的; AcceptEx()ConnectEx()DisconnectEx()TransmitFile()、HTTP.sys、API、RIOAPI等

复制自 site

支持的I/O 函数

以下函数可用于启动 I/O 使用 I/O 完成端口完成的操作。您必须向函数传递 OVERLAPPED 结构的实例和先前与 I/O 完成端口关联的文件句柄(通过调用 CreateIoCompletionPort)以启用 I/O

完成端口机制:

  1. ConnectNamedPipe
  2. DeviceIoControl
  3. LockFileEx
  4. ReadDirectoryChangesW
  5. 读取文件
  6. TransactNamedPipe
  7. WaitCommEvent
  8. 写入文件
  9. WSASendMsg
  10. WSASendTo
  11. WSASend
  12. WSARecvFrom
  13. WSARecvMsg
  14. WSARecv