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

closesocket后的Windows套接字完成例程回调,windows,sockets,overlapped-io,Windows,Sockets,Overlapped Io,在忙着以重叠模式使用Windows套接字并使用完成例程(因此没有IOCP)进行反馈时,我发现了以下奇怪的情况: 使用listen和AcceptEx打开服务器套接字 使用ConnectEx 我们现在有(至少)3个套接字:1个列表套接字、一个客户端连接的套接字和一个服务器连接的套接字 传输一些数据后,我们通过shutdown关闭服务器和客户端连接的套接字。完成此步骤后,两个插座都将使用closesocket关闭 目前:为了确保我们没有挂起的完成例程,我发布了以下(伪代码): 而SleepEx(0,T

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

  • 使用
    listen
    AcceptEx
    打开服务器套接字
  • 使用
    ConnectEx
  • 我们现在有(至少)3个套接字:1个列表套接字、一个客户端连接的套接字和一个服务器连接的套接字

    传输一些数据后,我们通过
    shutdown
    关闭服务器和客户端连接的套接字。完成此步骤后,两个插座都将使用
    closesocket
    关闭

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

    而SleepEx(0,TRUE)=WAIT\u IO\u COMPLETION do

    我现在想,释放
    WSARecv
    WSASend
    使用的
    OVERLAPPED
    结构的内存是可以节省的

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

    问题:


    何时才能确保不再使用完成例程对使用重叠IO的套接字发出完成回调?

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

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

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


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

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

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

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


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

    @RbMm:这里没有IOCP。@BenVoigt-但是
    AcceptEx
    ConnectEx
    呢?在异步模式下使用它的唯一方法是为iocp绑定套接字。不清楚什么是OPdoing@RbMm:您可以在没有完成端口的情况下完成异步I/O。@BenVoigt-depend from api
    AcceptEx
    ConnectEx
    仅与iocp低异步。此api没有APC选项,此处没有回调作为参数。不是吗?或OP使用同步的
    AcceptEx
    ConnectEx
    ?@RbMm:没有回调,但重叠结构中有一个事件句柄。导致他出现问题的实际操作是有回调参数的
    WSARecv
    。@RbMm:这里没有IOCP。@BenVoigt-但是
    AcceptEx
    ConnectEx
    呢?在异步模式下使用它的唯一方法是为iocp绑定套接字。不清楚什么是OPdoing@RbMm:您可以在没有完成端口的情况下完成异步I/O。@BenVoigt-depend from api
    AcceptEx
    ConnectEx
    仅与iocp低异步。此api没有APC选项,此处没有回调作为参数。不是吗?或OP使用同步的
    AcceptEx
    ConnectEx
    ?@RbMm:没有回调,但重叠结构中有一个事件句柄。导致他出现问题的实际操作是
    WSARecv
    ,它有一个回调参数。Ok。因此,对于每个未完成的WSARecv和WSASend,我都会记账,当回调返回时,我可以清理重叠的结构和套接字包装器对象。但这意味着必须保证回调将被调用,否则我可能会无限期地等待回调,因此会出现内存泄漏。我找不到操作系统是否保证这一点。这有保证吗?如果您从初始调用中获得了
    WSAEWOULDBLOCK
    ,则保证在操作结束时获得回调,无论是成功、失败还是取消。从MSDN:0(确定)和WSAEWOULDBLOCK都返回保证回调。那么记账就是了。因此,对于每个未完成的WSARecv和WSASend,我都会记账,当回调返回时,我可以清理重叠的结构和套接字包装器对象。但这意味着必须保证回调将被调用,否则我可能会无限期地等待回调,因此会出现内存泄漏。我不知道这是否有保证