这是一个带有使用 IOCP 的套接字的服务器。 我初始化了一个 OVERLAPPED 池,用它来发送 WSASend() 调用。 每个 WSASend() 调用都会从池中取出一个 OVERLAPPED 指针,并在收到通知时将其放回 IOCP 工作线程中。
但是,当客户端断开连接时,一些待处理的 WSASend() 调用会被丢弃,因此我没有机会回收从池中取出的重叠指针。
如何 100% 取消所有待处理的 WSASend() 调用,同时确保它们不会到达 IOCP 工作线程,以便我可以在断开连接时手动回收 OVERLAPPED 指针?
谢谢。
最佳答案
这不是 IOCP 的工作方式。
如果您有要取消的待处理操作,请关闭相应的套接字,操作将完成或失败,并且所有完成(包括失败)最终都会从 IOCP 中得出。
您需要等待这种情况发生,一旦发生,您就可以关闭了。
我倾向于做的是有一个“每个连接”结构,其中包含套接字并用作完成键。然后我有“每个操作”结构,其中包括重叠,还包括操作类型、使用的 I/O 缓冲区和其他内容的详细信息。这两个结构都是引用计数的。
启动操作时,您会增加连接对象和操作对象的引用计数。当您完成时,您对其进行处理,然后减少计数。当计数达到 0 时,您不再对对象进行任何操作,它们可以回收到池中以供重用。
为了帮助彻底关闭,我有一个可以等待的计数器,它跟踪“事件”“每个连接”对象(套接字)的数量。
要关闭,您需要中止所有连接,然后等待连接计数器为零。那时,您的所有对象要么被销毁,要么在池中,您可以清理。
我有一些示例代码,here ,这是一组功能齐全的 IOCP 服务器示例,可能会有所帮助 - 这是工作代码,您可以单步执行并从中获取想法。
关于sockets - 带有 WSASend 和 OVERLAPPED 池的 IOCP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16726026/