我的问题很少,都与keep_alive
有关。
basic_socket_acceptor::keep_alive
和basic_stream_socket::keep_alive
之间有什么区别?什么时候用哪个? ip::tcp::acceptor
使用任何类型的keep_alive
?它对我没有意义,因为对于接受者而言没有连接,但是它也有keep_alive
选项,因此混乱。keep_alive
,那么Boost Asio检测到连接断开时的行为是什么?它是如何/何时通知用户代码的?它会抛出异常吗?如果是这样,哪个例外?我在文档中没有看到任何此类详细信息。答案 0 :(得分:3)
basic_socket_acceptor :: keep_alive和。之间的区别是什么? basic_stream_socket :: KEEP_ALIVE?何时使用哪个?
两者都是一样的。在文档中,它显示在basic_socket_acceptor
和basic_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_alive
和basic_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
传递给应用程序的方式与提供其他错误代码的方式相同。应该参考操作系统的文档来确定写操作的预期错误代码:
WSASend()
被记录为返回WSAENETRESET
(boost::asio::error:: connection_reset
)ETIMEOUT
(boost::asio::error::timed_out
)。如果响应保持活动探测而返回ICMP错误,则将返回相关的ICMP错误。例如,可以观察到EHOSTUNREACH
(boost::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
错误。