【发布时间】:2020-02-29 13:24:39
【问题描述】:
场景:
我有一个使用boost::asio 1.63 编写的客户端和服务器。一般来说,连接和通信部分工作得很好。
我在双方都编写了一个看门狗,它以 2 秒的间隔向对等方发送虚拟数据包。看门狗的目标是,如果相关对等方在接下来的 2 秒内没有收到它所期望的虚拟数据包,则它会报告连接错误。这对我来说甚至更重要,因为这可能会发生 2 个对等点没有出于任何用户目的处理数据包,但是如果任何对等点出现故障,他们每个人都需要报告连接错误。即使由于内核崩溃,对等方也可能出现故障,在这种情况下,该对等方将无法发送消息。这当然是一个经典的问题,甚至超越了 asio 和 TCP。
我的看门狗运行良好。完全没有问题。
但是,最近我读到了套接字中的keep_alive 功能。我尝试了以下代码,似乎可以通过使用 boost::asio 从我的代码中获取套接字的本机句柄来在 TCP 套接字上调用一个名为 keep_alive 的属性。
boost::asio::io_service ioService;
boost::asio::ip::tcp::socket mySocket(ioService);
int on = 1;
int delay = 120;
setsockopt(mySocket.native_handle(), SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
setsockopt(mySocket.native_handle(), IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay));
问题:
上面的代码在 macOS、Linux 和 iOS 上编译良好。看起来很棒。但是,我如何从中受益?当对等体出现故障时,这会给我一个回调或事件吗?这能让我从编写上面描述的看门狗中解放出来吗?
我已使用boost::asio::async_connect 连接到对等方。当 perr 在定义的超时间隔后下降时,我可以回调我的 connectionHandler 吗?
设置了keep_alive 选项后,我如何才能知道我的对等方不再响应?
【问题讨论】:
-
你不需要原始的
setsockopt,你可以使用mySocket.set_option -
Does this give me a callback or event when the peer goes down?我认为它会失败并在您的读写操作中出现退出代码。 -
It wouldn't send me an event if my peer is sitting idle and not doing any read/write.正确,但是什么时候会发生这种情况?您通常会总是等待数据读取,不是吗? -
TCP keepalive (a) 默认关闭 (b) 启用时,默认以两小时间隔运行 (c) 如果下次使用套接字进行 I/O,则会导致连接重置检测到死节点。
-
@AdeleGoldberg 我对你如何让它工作很感兴趣。你能写一个(非常)简短的摘要作为self-answer吗?
标签: sockets tcp boost-asio tcp-keepalive