Boost.Asio套接字析构函数会关闭连接吗?

13

boost::asio::ip::tcp::socket 的析构函数具体做了什么?即使我看遍了 Boost 文档和源代码,也无法确定是否需要使用它。

socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
socket->close();

在调用之前

delete socket;

在使用完套接字后,我需要手动关闭套接字吗?还是析构函数会处理这个问题?


源代码来看,它似乎没有一个。 - amanuel2
我知道。这很奇怪,因为看起来套接字应该执行一些清理工作,但我认为我还没有找到正确的代码片段。 - owacoder
不,这一定是正确的代码,因为它直接来自于 Boost 网站,除非有一些奇怪的活动正在进行。但重点是没有析构函数,所以你必须自己关闭和终止套接字。明白吗? - amanuel2
@amanuel2 请看我的回答。 - sehe
1
@amanuel2 所有的 I/O 对象都将其清理工作推迟到它们所继承的 basic_io_object 中进行处理。 - Tanner Sansbury
除非你正在处理一个已被继承且你真的想现在关闭的套接字,否则在关闭之前不需要调用“both”关机。 - user207421
3个回答

10
当一个 socket 被销毁时,它将在 socket 销毁期间被 仿佛 socket.close(ec) 关闭。

输入/输出对象,例如socket,继承自basic_io_object。在basic_io_object析构函数中,将在I/O对象的I/O服务上调用destroy(),并传入一个implementation_type实例,该实例将操作I/O对象的服务。在socket的情况下,将在满足SocketService类型要求的类型上调用destroy(),关闭底层socket。在下面的文档中,a是socket服务类的实例,b是socket服务类的implementation_type的实例:

a.destroy(b):

[...] 隐式地取消异步操作,就像调用 a.close(b, ec) 一样。

a.close(b, ec):

如果 a.is_open() 为真,则尽快完成所有未完成的异步操作。对于已取消的操作,处理程序应传递错误代码 error::operation_aborted

后置条件:!a.is_open(b)


4
答案忽略了shutdown()的问题。从close()的文档中可以得知,在关闭套接字之前,应调用shutdown()以确保连接的优雅关闭具有可移植性。
如果删除套接字会隐式地关闭它,那么在删除之前仍建议调用shutdown()。

4

是的,他必须手动关闭套接字连接,并自己实现“析构函数”。 很好的回答。 - amanuel2
1
@sehe - 析构函数是否干净地断开连接,执行所提出的两个调用?还是它只是突然关闭连接? - owacoder
2
@amanuel2 不需要手动关闭套接字连接,也不需要自己实现析构函数。毫无意义的评论。 - user207421
@EJP 是的,他必须手动关闭套接字,代码如下:socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both); socket->close(); - amanuel2
2
@amanuel,如果您发现套接字的析构函数没有关闭底层本机套接字,请向Asio提交错误报告。根据文档和实现,本机套接字应在套接字销毁期间关闭。 - Tanner Sansbury

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