使用 boost::asio 配置 TCP keep_alive

2021-12-28 00:00:00 tcp c++ boost-asio

Linux 和 Windows 都支持 TCP keep-alive 数据包.它们可以通过(依赖于系统的)setsockopt 调用来激活和配置,参见例如这篇文章 适用于 Linux 案例.使用 boost::asio 时,似乎支持保持活动消息,请参阅 当前文档.但是,该页面仅涵盖激活它.在对旧帖子 有人指出 Boost 最近增加了在操作上配置超时的方法(这避免了对不同系统的 setsockopt#ifdef 代码分支的需要).但是,最近的回复 仍然建议调用本机套接字.

Both Linux and Windows support TCP keep-alive packets. They can be activated and configured with (system-dependent) setsockopt calls, see e.g. this article for the Linux case. When using boost::asio there appears to be support for keep-alive messages, see the current documentation. However that page only covers activating it. In several new responses to an older post it was pointed out that Boost has recently added the means to configure timeouts on operations (which obviates the need for setsockopt and #ifdef code-branches for different systems). However, a recent response still suggests calls on the native sockets.

我的问题是:如何使用 boost::asio 配置保持活动数据包的时间间隔和超时?

My question is: How can I configure the time interval and timeouts of keep-alive packets using boost::asio?

推荐答案

您可以使用 setsockopt 选项配置发送超时和接收超时.下面是一些在 windows 和 linux/unix 上执行此操作的平台相关代码,该示例将发送和接收超时设置为相同的 10 秒值:

You can configure both the send timeout and receive timeout using the setsockopt options. Here is some platform-dependent code to do this on both windows and linux / unix, the example sets both send and receive timeouts to the same ten second value:

// start IO service    
io_context = new boost::asio::io_context;        

// define a tcp socket object    
tcpsocket = new boost::asio::ip::tcp::socket(*io_context); 

// the timeout value
unsigned int timeout_milli = 10000;

// platform-specific switch
#if defined _WIN32 || defined WIN32 || defined OS_WIN64 || defined _WIN64 || defined WIN64 || defined WINNT
  // use windows-specific time
  int32_t timeout = timeout_milli;
  setsockopt(tcpsocket->native_handle(), SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
  setsockopt(tcpsocket->native_handle(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout));
#else
  // assume everything else is posix
  struct timeval tv;
  tv.tv_sec  = timeout_milli / 1000;
  tv.tv_usec = (timeout_milli % 1000) * 1000;
  setsockopt(tcpsocket->native_handle(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
  setsockopt(tcpsocket->native_handle(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
#endif

相关文章