从完成端口"Un-associate"套接字

"Un-associate" socket from completion port

本文关键字:Un-associate 套接字      更新时间:2023-10-16

CreateIoCompletionPort()用于关联套接字和完成端口。然而,当这个套接字关闭时,我需要将它与完成端口"解除关联"。我该怎么做呢?

微软显然不希望普通用户这样做,但尽管如此,有一个官方文档的方法(它只需要大量的挖掘来找到它):

调用NtSetInformationFile,为FileInformationClass参数传递值FileReplaceCompletionInformation,将完成此操作。(此值在FILE_INFORMATION_CLASS中定义)

该参数值(强调我的)的描述的副本:

更改或删除指定文件句柄的I/O完成端口。调用者提供一个指向FILE_COMPLETION_INFORMATION结构的指针它指定一个端口句柄和一个完成键。如果端口句柄是非null,此句柄指定要关联的新I/O完成端口文件句柄。移除I/O完成端口文件句柄,将结构中的端口句柄设置为NULL。要获取端口句柄,用户模式调用者可以调用CreateIoCompletionPort函数。

当句柄关闭时,与I/O完成端口关联的句柄将从该端口移除。如果是网络套接字,则通过调用closesocket()来关闭句柄。

CreateIoCompletionPort的文档包含关于资源处理的注释:

FileHandle参数传递的句柄可以是任何支持重叠I/O的句柄。最常见的是,这是一个由CreateFile函数使用FILE_FLAG_OVERLAPPED标志打开的句柄(例如,文件、邮件槽和管道)。由其他函数(如socket)创建的对象也可以与I/O完成端口相关联。有关使用套接字的示例,请参见AcceptEx。一个句柄只能与一个I/O完成端口关联,关联完成后,该句柄将一直与该I/O完成端口关联,直到该端口关闭

I/O完成端口句柄和与该特定I/O完成端口相关联的每个文件句柄被称为对I/O完成端口的引用。当I/O完成端口不再被引用时,该端口将被释放。因此,必须正确关闭所有这些句柄,以释放I/O完成端口及其相关的系统资源。满足这些条件后,通过调用CloseHandle函数关闭I/O完成端口句柄。