代码之家  ›  专栏  ›  技术社区  ›  Ritsaert Hornstra

closesocket之后的Windows套接字完成例程回调

  •  0
  • Ritsaert Hornstra  · 技术社区  · 8 年前

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

    1. 使用打开服务器套接字 listen AcceptEx .
    2. 使用 ConnectEx

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

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

    当前:为了确保没有挂起的完成例程,我发布了以下代码(伪代码):

    当SleepEx(0,TRUE)==等待IO完成时;

    我想现在可以省钱去回忆 OVERLAPPED 使用的结构 WSARecv WSASend .

    当线程再次处于可警报状态时,将对服务器连接的套接字执行另一个完成例程回调,返回错误10053,但使用 重叠的 我们刚刚释放的结构。这是空闲后的内存使用。

    问题:

    什么时候你能确定一个使用重叠IO的socket使用完成例程不再发出完成回调呢?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Ben Voigt    8 年前

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

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

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

    跟踪每个挂起操作的套接字,并使用 WaitForSingleObjectEx 而不是 梦游者 ,以显式地等待每一个。

    推荐文章