0

场景:
我有一个使用boost::asio 1.63编写的客户端和服务器。一般来说,连接和通信部分工作得很好。

我在两边都写了一个看门狗,它以 2 秒的间隔向对等方发送虚拟数据包。看门狗的目标是,如果相关对等方在接下来的 2 秒内没有收到它所期望的虚拟数据包,则它会报告连接错误。这对我来说甚至更重要,因为这两个对等点可能不会出于任何用户目的处理数据包,但是如果任何对等点出现故障,它们中的每一个都需要报告连接错误。即使由于内核崩溃,对等方也可能出现故障,在这种情况下,该对等方将无法发送消息。这当然是一个经典问题,甚至超越了 asio 和 TCP。

我的看门狗运行良好。完全没有问题。

但是,最近我读到了套接字中的keep_alive功能。我尝试了以下代码,似乎我可以通过在我的代码中使用boost::asio.

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选项后,我如何才能知道我的对等方不再响应?

4

1 回答 1

0

如果在异步操作挂起时检测到断开连接,则会使用适当的错误代码调用套接字的完成处理程序。

问题是 TCP keep_alive 选项并不总是检测到断开连接。

一般来说,没有可靠的方法来检测突然断开连接,除了实现应用程序级别的 ping/heartbeat。

你也可以看到这个线程

于 2019-11-13T18:23:30.303 回答