c - 从 I/O 完成端口中删除句柄以及有关 IOCP 的其他问题

标签 c windows file sockets iocp

CreateIoCompletionPort函数允许创建新的 I/O 完成端口并将文件句柄注册到现有的 I/O 完成端口。

然后,我可以使用任何函数,例如套接字上的 recv 或具有 OVERLAPPED 结构的文件上的 ReadFile 来启动一个异步操作。

我必须检查函数调用是否同步返回,尽管它是用 OVERLAPPED 结构调用的,在这种情况下直接处理它。在另一种情况下,当返回 ERROR_IO_PENDING 时,我可以使用 GetQueuedCompletionStatus操作完成时得到通知的函数。

出现的问题是:

  • 如何从 I/O 完成端口删除句柄?例如,当我向 IOCP 添加套接字时,如何删除已关闭的套接字?我是否应该使用相同的完成 key 重新注册另一个套接字?

  • 另外,有没有办法让调用始终通过 I/O 完成端口并且不同步返回?

  • 最后,是否有可能以异步方式recv 而以同步方式send?例如,当实现一个简单的 echo 服务时:我可以使用异步 recv 等待新数据,但以同步方式 send 响应,从而降低代码复杂性吗?就我而言,无论如何,在处理第一个请求之前,我不会第二次recv

  • 如果已请求异步 ReadFile,但在它完成之前,应该处理对同一文件的 WriteFile,会发生什么情况。 ReadFile 是否会因错误消息而被取消,并且我必须在写入完成后立即重新启动读取过程?或者我必须在写入之前手动取消 ReadFile 吗?这个问题与通信设备结合使用;因此,写入和读取如果同时发生应该不会出现问题。

最佳答案

How can I remove a handle from the I/O completion port?

根据我的经验,您无法解除句柄与完成端口的关联。但是,您可以通过设置 OVERLAPPED 结构的 hEvent 字段的低位来禁用完成端口通知:请参阅 GetQueuedCompletionStatus 的文档。 .

For example, when I add sockets to the IOCP, how can I remove closed ones? Should I just re-register another socket with the same completion key?

没有必要显式地解除句柄与 I/O 完成端口的关联;关闭 handle 就足够了。您可以将多个句柄与同一个完成键相关联;确定哪个请求与 I/O 完成相关联的最佳方法是使用 OVERLAPPED 结构。事实上,你甚至可以extend OVERLAPPED存储额外的数据。

Also, is there a way to make the calls ALWAYS go over the I/O completion port and don't return synchronously?

这是默认行为,即使 ReadFile/WriteFile 返回 TRUE。您必须显式调用 SetFileCompletionNotificationModes告诉 Windows 在返回 TRUEERROR_SUCCESS 时不要排队完成数据包。

is it possible for example to recv asynchronously but to send synchronously?

不是通过使用recvsend;您需要使用接受 OVERLAPPED 结构的函数,例如 WSARecv , WSASend ,或者 ReadFileWriteFile .如果您的代码旨在处理多种类型的 I/O 句柄,例如套接字和命名管道,那么使用后者可能更方便。这些函数提供同步模式,因此如果您使用它们,您可以混合使用异步和同步调用。

What happens if an asynchronous ReadFile has been requested, but before it completes, a WriteFile to the same file should be processed?

没有隐式取消。只要您对全双工设备的每次读/写都使用单独的 OVERLAPPED 结构,我看不出您不能执行并发 I/O 操作的原因。

关于c - 从 I/O 完成端口中删除句柄以及有关 IOCP 的其他问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6573218/

相关文章:

c - 用 scanf 读取 int 直到换行

c - 如何计算递增变量的总计

c - 我想在我的winapi C程序中画图,有什么控制吗?

c - 如何检测蓝牙 HID 设备是否断开连接?

Java如何通过分隔符字符串将文本文件分隔为文件

c - 尝试创建txt文件,但提示无法打开文件

C - 指针的初始化,星号位置

比较 double 产生一个少一个和等于另一个

windows - 移动具有特定名称的所有文件(排序)WINDOWS 8

C 段错误 11