场景:
我有一个使用boost::asio 1.63编写的客户端和服务器。我正在tcp套接字中使用keep_alive功能来检测连接丢失。
以下是keep_alive
代码设置。
boost::asio::io_service ioService;
boost::asio::ip::tcp::socket mySocket(ioService);
#ifdef __APPLE__
unsigned int timeoutMillis = 2000;
struct timeval tvs;
tvs.tv_sec = timeoutMillis / 1000;
tvs.tv_usec = (timeoutMillis % 1000) * 1000;
if (setsockopt(mySocket.native_handle(),SOL_SOCKET,SO_RCVTIMEO,&tvs,sizeof(tvs)) == -1) {
throw std::logic_error("Cannot set SO_RCVTIMEO");
}
if (setsockopt(mySocket.native_handle(),SO_snDTIMEO,sizeof(tvs)) == -1) {
throw std::logic_error("Cannot set SO_RCVTIMEO");
}
#elif __linux__
int32_t timeout = 2;
int32_t cnt = 1;
int32_t interval = 2;
if (setsockopt(mySocket.native_handle(),SOL_TCP,TCP_KEEPIDLE,&timeout,sizeof(timeout)) == -1) {
throw std::logic_error("Cannot set TCP_KEEPIDLE");
}
if (setsockopt(mySocket.native_handle(),TCP_KEEPCNT,&cnt,sizeof(cnt)) == --1) {
throw std::logic_error("Cannot set TCP_KEEPCNT");
}
if (setsockopt(mySocket.native_handle(),TCP_KEEPINTVL,&interval,sizeof(interval)) == -1) {
throw std::logic_error("Cannot set TCP_KEEPINTVL");
}
#elif WIN32
我两边都有boost::asio::async_read
,总是在等待数据。当另一个对等方退出时,它将返回错误。因此,检测到连接丢失。这种逻辑在服务器端的 Linux 和客户端的 Android 上都可以很好地工作。
问题:
如果我通过单击关闭按钮以适当的方式退出对等方,则说明一切正常。如果我关闭Android设备上的wifi,则2秒后会出现错误。 但是,那不会发生。
我也在macOS上测试了此代码。完全一样的问题!就像在发生“ 进程对等出口”的情况下发生的情况一样,当/如果关闭了wifi,我是否不应该期望从boost::asio::async_read
返回错误的消息吗? keep_alive中的解释指出,即使服务器端的内核崩溃,它也可以工作。我是否还想在tcp套接字上设置一些其他属性?