我在 UDP 套接字上使用 IOCP,UDP 套接字可能在另一个线程中关闭。那么,如何安全地释放与 SOCKET 关联的 Per Socket Context 和 Per I/O Context 呢?
当我关闭套接字时,内核队列中仍然会有未完成的 I/O 请求。
如果我在套接字关闭时释放上下文,则 GetQueueCompletionStatus 可能会失败。
现在,我的问题是何时释放上下文?
我在 UDP 套接字上使用 IOCP,UDP 套接字可能在另一个线程中关闭。那么,如何安全地释放与 SOCKET 关联的 Per Socket Context 和 Per I/O Context 呢?
当我关闭套接字时,内核队列中仍然会有未完成的 I/O 请求。
如果我在套接字关闭时释放上下文,则 GetQueueCompletionStatus 可能会失败。
现在,我的问题是何时释放上下文?
我对所有每个套接字和每个 I/O 数据结构都使用引用计数。它使这种事情变得容易,因为当它们的引用下降到 0 时它们被删除。对于一些显示一种方法的示例代码,您可以查看我的免费 IOCP 框架,您可以从这里下载。
使用互斥锁在代码的关键部分强制互斥,这将检查套接字的可用性,并在必要时打开它。将套接字锁定到该线程,并在完成后适当地释放它。
我重用我的每个套接字结构。在我收到该连接所需的所有读写操作的完成事件后,我使用 and 标志调用TransmitFile
以TF_DISCONNECT
重置TF_REUSE_SOCKET
套接字,而无需关闭它。一旦TransmitFile
呼叫的完成事件通过,我还会重置每个连接的数据。
先关闭插座。你会从 GetQueuedCompletionStatus 得到错误(我认为是 ERROR_OPERATION_ABORTED),然后是释放结构的正确时间。此时内核队列中该连接上没有其他未完成的请求,完成包按FIFO顺序维护,错误包肯定是该连接的最后一个。