销毁 Boost Asio 套接字而不关闭本机处理程序

4
我遇到了以下问题。我想要在使用boost Asio的第三方库中注入一些socket描述符到io_service事件循环中。
我的做法是创建一个boost::asio::ip::tcp::socket并传递本地处理程序提供的原生处理程序。
问题在于,该库只会通信,不关心特定socket通知(这意味着该库可能会在稍后关闭或重用该socket)。无论如何,我都想清理boost套接字并销毁它们,但不关闭原生处理程序(即文件描述符)。
简而言之,有没有办法在不关闭底层处理程序的情况下销毁boost::asio::ip::tcp::socket?我知道可以使用posix::stream_descriptor,但我希望我的解决方案具有可移植性。

你是否尝试过给一个无效的套接字assign,即使它失败了,之前的套接字也可能不再可用... - Jean Davy
@JeanDavy socket.assign(protocol, native) 有一个前提条件,即 socket 没有打开(请参见 SocketService)。如果未满足此前提条件,则 socket 的状态将保持不变。 - Tanner Sansbury
3个回答

2
没有办法在不关闭原生句柄的情况下销毁ip::tcp::socket。这是无法进行可移植实现的,因此Asio不支持它。特别地,在Windows 8.1之前,一旦套接字与I/O完成端口相关联,只有通过关闭它才能取消关联1。请参阅this相关的github问题,其中Chris Kohlhoff回应了这个功能请求:

不支持这个功能,因为它无法进行可移植实现。具体来说,在Windows上,套接字被关联到一个I/O完成端口中,无法解除关联。

如果你只针对基于POSIX的系统,则可以将描述符放入posix::stream_descriptor中吗?该类提供了一个release()成员函数。


1. Windows 8.1支持通过FileReplaceCompletionInformation来解除完成端口关联,而无需关闭套接字。

在常规的Windows应用程序中是否可以使用NtSetInformationFile?这是为驱动程序保留的吗? - Alex

0
但我希望我的解决方案是可移植的。
一旦你触及本地句柄,程序就不再是可移植的了。
然而,一旦你接受了这一点,你可以在本地句柄上调用dup() [unix]或DuplicateHandle() [windows]。

实际上,我并不打算触碰本地句柄,Asio和其他库在Windows和Unix中都使用相同类型的本地句柄。 - sapito

0

您可以尝试切换到posix::stream_descriptor并使用其release方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接