boost tcp acceptor和boost tcp socket的keep_alive选项

时间:2016-11-05 05:11:03

标签: c++ sockets boost tcp boost-asio

我的问题很少,都与keep_alive有关。

  • basic_socket_acceptor::keep_alivebasic_stream_socket::keep_alive之间有什么区别?什么时候用哪个?
  • 我们是否需要对ip::tcp::acceptor使用任何类型的keep_alive?它对我没有意义,因为对于接受者而言没有连接,但是它也有keep_alive 选项,因此混乱。
  • 如果设置了keep_alive,那么Boost Asio检测到连接断开时的行为是什么?它是如何/何时通知用户代码的?它会抛出异常吗?如果是这样,哪个例外?我在文档中没有看到任何此类详细信息。

3 个答案:

答案 0 :(得分:3)

  

basic_socket_acceptor :: keep_alive和。之间的区别是什么?   basic_stream_socket :: KEEP_ALIVE?何时使用哪个?

两者都是一样的。在文档中,它显示在basic_socket_acceptorbasic_stream_socket下,因为它们都来自socket_base keepalive选项实际可见(它是typedef)。

根据文档中的示例,您将始终使用它:

boost::asio::socket_base::keep_alive option(true);
socket.set_option(option);
  

我们是否需要对ip :: tcp :: acceptor使用任何类型的keep_alive?

不,你没有,你不能。 set_option无论如何只能在套接字对象上调用(我相信只有在套接字为opened之后)。

  

如果设置了keep_alive,那么Boost Asio的行为是什么时候呢   检测到断开的连接?

这取决于平台。在linux上,当keep_alive探测失败时,您将收到broken pipe错误或EPOLLERR / EPOLLHUP

更新(来自我的评论):

此故障不会传播到用户代码。因此,您可能需要实现应用程序级别ping或使用超时套接字选项。

答案 1 :(得分:2)

basic_socket_acceptor::keep_alivebasic_stream_socket::keep_alive是相同的。该文档指出它们都是从定义socket_base选项的socket_base::keep_alive类继承而来的。

  

<强> basic_stream_socket::keep_alive

     

继承自socket_base。

     

发送保持活动的套接字选项。

虽然侦听套接字上的keep-alive对侦听套接字没有直接用处,但在某些系统上,新接受的套接字从侦听套接字继承了一些套接字选项。继承的套接字选项通常是影响必须在accept()返回之前完成的TCP三次握手的选项,例如SO_KEEPALIVE。因此,Asio支持在接受器上设置keep-alive选项;但是,Asio不会将套接字选项复制到新套接字。

保持活动功能允许 write 操作被通知连接断开,这由保持活动机制 1 确定。因此,当keep-alive探针失败时,套接字上的下一个Asio写操作将失败 2 ,将error_code传递给应用程序的方式与提供其他错误代码的方式相同。应该参考操作系统的文档来确定写操作的预期错误代码:

  • 在Windows上,WSASend()被记录为返回WSAENETRESETboost::asio::error:: connection_reset
  • 在Linux上,错误将根据保持活动探测失败的方式而有所不同。如果没有响应,则会出现ETIMEOUTboost::asio::error::timed_out)。如果响应保持活动探测而返回ICMP错误,则将返回相关的ICMP错误。例如,可以观察到EHOSTUNREACHboost::asio::error::host_unreachable)被返回

 1.请参阅RFC 1122中指定的 Internet主机要求 - 通信层的4.2.3.6  2. SO_KEEPALIVE通过SIGPIPE信号通知线程写入套接字,但Asio明确禁止在写操作上接收SIGPIPE。因此,底层系统调用将返回相关错误

答案 2 :(得分:1)

这取决于您所运行的平台。在Linux上,如果您确实执行以下操作,

boost::asio::socket_base::keep_alive option(true);
socket.set_option(option);

然后,基本上可以保护您免受可能会导致套接字上的读取或写入错误的较小网络中断的影响。如果您在套接字指针上将keep_alive设置为true,则有几种方法可以检测到您正在读/写的套接字上的错误:

  • 首先,您可以通过实现在对等体之间的间隔中发送健康数据包的乒乓机制来检测套接字错误。

  • 或者,当您从套接字返回boost::asio::error::eof错误时也可以检测到错误,这基本上意味着对等方已关闭连接。请注意,如果连接被同级关闭,对套接字的读取仍然可以返回boost::asio::error::eof错误。