本文介绍了如何使用TCP keep_alive属性在无响应的对等事件时得到通知?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景:
我有一个使用 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选项后,如何知道对等方不再响应了?

解决方案

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

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

通常,除了实现应用程序级ping/心跳之外,没有可靠的方法来检测突然断开连接.

您还可以看到此线程.

Scenario:
I have a client and server written using boost::asio 1.63. Generally the connection and communication part works well and great.

I have written a Watchdog on both sides which send dummy packets to peers in an interval of 2 seconds each. The objective of the watchdog is that the concerned peer reports a connection error if it does not receive the dummy packet it is expecting in the next 2 seconds. This is even more important for me because it might happen the 2 peers are not transacting packets for any user purpose but each of them is required to report a connection error if any of the peer goes down. The peer can go down even because of a kernel crash in which case it would not be possible for that peer to send a message. This is a classic problem of course which exists even beyond asio and TCP.

My Watchdog works perfectly well. No issues at all.

But, recently I read about the keep_alive feature in sockets. I tried out the following code and seems like I can a property called keep_alive on the TCP socket by getting the native handle to the socket from within my code using 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));

Question:
Above code compiles well on macOS, Linux and iOS. That looks great. But, how do I benefit from this? Does this give me a callback or event when the peer goes down? Does this free me up from writting the Watchdog that I described above?

I have used boost::asio::async_connect to connect to the peer. Can I get a callback to my connectionHandler when the perr goes down after the defined timeout interval?

Having set the keep_alive options, how do I then get to know that my peer is not responding anymore?

解决方案

If the disconnetion was detected when an async operation is pending, your socket's completion handler will be invoked with the appropriate error code.

The problem is that TCP keep_alive option doesn't not always detect disconnects.

In general, there is no reliable way to detect sudden disconnection, other than by implementing application-level ping/heartbeat.

You can also see this thread.

这篇关于如何使用TCP keep_alive属性在无响应的对等事件时得到通知?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 23:44