Windows 关闭套接字后套接字完成例程回调

Windows socket completion routine callback after closesocket

当忙于在重叠模式下使用 Windows 套接字并使用完成例程(因此没有 IOCP)进行反馈时,我发现了以下奇怪的情况:

  1. 使用 listenAcceptEx 打开服务器套接字。
  2. 使用 ConnectEx
  3. 在所述端口上连接客户端套接字

我们现在有(至少)3 个套接字:1 个列表套接字、一个客户端连接的套接字和一个服务器连接的套接字。

传输一些数据后,我们使用 shutdown 关闭服务器和客户端连接的套接字。在这一步之后,两个套接字都用 closesocket.

关闭

目前:为了确保我们没有未决的完成例程,我发出以下(伪代码):

while SleepEx( 0, TRUE ) == WAIT_IO_COMPLETION 做 ;

我认为现在释放 WSARecvWSASend 所使用的 OVERLAPPED 结构的内存是可以节省的。

这一刻之后,当线程再次进入可警报状态时,另一个完成例程回调为服务器连接的套接字完成,错误为 10053,但使用我们刚刚释放的 OVERLAPPED 结构。这是释放后内存的使用。

问题:

你什么时候可以确定不再为使用完成例程的重叠 IO 的套接字发出完成回调?

您需要等待 I/O 完成(关闭套接字将取消未完成的请求,您将获得完成回调)。

OS 拥有 OVERLAPPED 结构和关联缓冲区的所有权,直到您在事件完成时进行同步(通过等待 hEvent 或接收 APC)。在收到此回调之前,您不能对缓冲区执行任何操作,并且绝对不能释放它。等待 OS 告诉您不再需要它。

请注意,取消不一定会立即完成,因为驱动程序可能正在与硬件请求同步,并且仅在硬件状态更改时才将 IRP 标记为完成。 (如果正在使用 DMA,这将是必要的,但可能只是为了一致性而对其他操作完成)因此,不能保证您显示的 SleepEx 循环收集所有取消。

跟踪挂起操作的每个套接字,并使用 WaitForSingleObjectEx 而不是 SleepEx,明确等待每个套接字。