Windows 关闭套接字后套接字完成例程回调
Windows socket completion routine callback after closesocket
当忙于在重叠模式下使用 Windows 套接字并使用完成例程(因此没有 IOCP)进行反馈时,我发现了以下奇怪的情况:
- 使用
listen
和 AcceptEx
打开服务器套接字。
- 使用
ConnectEx
在所述端口上连接客户端套接字
我们现在有(至少)3 个套接字:1 个列表套接字、一个客户端连接的套接字和一个服务器连接的套接字。
传输一些数据后,我们使用 shutdown
关闭服务器和客户端连接的套接字。在这一步之后,两个套接字都用 closesocket
.
关闭
目前:为了确保我们没有未决的完成例程,我发出以下(伪代码):
while SleepEx( 0, TRUE ) == WAIT_IO_COMPLETION 做 ;
我认为现在释放 WSARecv
和 WSASend
所使用的 OVERLAPPED
结构的内存是可以节省的。
这一刻之后,当线程再次进入可警报状态时,另一个完成例程回调为服务器连接的套接字完成,错误为 10053,但使用我们刚刚释放的 OVERLAPPED
结构。这是释放后内存的使用。
问题:
你什么时候可以确定不再为使用完成例程的重叠 IO 的套接字发出完成回调?
您需要等待 I/O 完成(关闭套接字将取消未完成的请求,您将获得完成回调)。
OS 拥有 OVERLAPPED 结构和关联缓冲区的所有权,直到您在事件完成时进行同步(通过等待 hEvent
或接收 APC)。在收到此回调之前,您不能对缓冲区执行任何操作,并且绝对不能释放它。等待 OS 告诉您不再需要它。
请注意,取消不一定会立即完成,因为驱动程序可能正在与硬件请求同步,并且仅在硬件状态更改时才将 IRP 标记为完成。 (如果正在使用 DMA,这将是必要的,但可能只是为了一致性而对其他操作完成)因此,不能保证您显示的 SleepEx
循环收集所有取消。
跟踪挂起操作的每个套接字,并使用 WaitForSingleObjectEx
而不是 SleepEx
,明确等待每个套接字。
当忙于在重叠模式下使用 Windows 套接字并使用完成例程(因此没有 IOCP)进行反馈时,我发现了以下奇怪的情况:
- 使用
listen
和AcceptEx
打开服务器套接字。 - 使用
ConnectEx
在所述端口上连接客户端套接字
我们现在有(至少)3 个套接字:1 个列表套接字、一个客户端连接的套接字和一个服务器连接的套接字。
传输一些数据后,我们使用 shutdown
关闭服务器和客户端连接的套接字。在这一步之后,两个套接字都用 closesocket
.
目前:为了确保我们没有未决的完成例程,我发出以下(伪代码):
while SleepEx( 0, TRUE ) == WAIT_IO_COMPLETION 做 ;
我认为现在释放 WSARecv
和 WSASend
所使用的 OVERLAPPED
结构的内存是可以节省的。
这一刻之后,当线程再次进入可警报状态时,另一个完成例程回调为服务器连接的套接字完成,错误为 10053,但使用我们刚刚释放的 OVERLAPPED
结构。这是释放后内存的使用。
问题:
你什么时候可以确定不再为使用完成例程的重叠 IO 的套接字发出完成回调?
您需要等待 I/O 完成(关闭套接字将取消未完成的请求,您将获得完成回调)。
OS 拥有 OVERLAPPED 结构和关联缓冲区的所有权,直到您在事件完成时进行同步(通过等待 hEvent
或接收 APC)。在收到此回调之前,您不能对缓冲区执行任何操作,并且绝对不能释放它。等待 OS 告诉您不再需要它。
请注意,取消不一定会立即完成,因为驱动程序可能正在与硬件请求同步,并且仅在硬件状态更改时才将 IRP 标记为完成。 (如果正在使用 DMA,这将是必要的,但可能只是为了一致性而对其他操作完成)因此,不能保证您显示的 SleepEx
循环收集所有取消。
跟踪挂起操作的每个套接字,并使用 WaitForSingleObjectEx
而不是 SleepEx
,明确等待每个套接字。