TCP keep_alive does not work if you switch off wifi to cause an abrupt connection loss

荒凉一梦 提交于 2019-12-02 20:03:02

问题


Scenario:
I have a client and server written using boost::asio 1.63. I am using keep_alive feature in tcp sockets to detect connection losses.

Following is the keep_alive code setup.

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(), SOL_SOCKET, SO_SNDTIMEO, &tvs, 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(), SOL_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)) == --1) {
        throw std::logic_error("Cannot set TCP_KEEPCNT");
    }
    if (setsockopt(mySocket.native_handle(), SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval)) == -1) {
        throw std::logic_error("Cannot set TCP_KEEPINTVL");
    }
#elif WIN32

I have a boost::asio::async_read on both sides always waiting for data. It returns error when the other peer exits. Hence a connection loss is detected. This logic works well on both Linux which is the Server side and Android which is the Client side.

Question:
If I exit a peer in a proper process way by clicking on the close button, then things work well. If I switch off the wifi on my Android device then I expect an error after 2 seconds. But, That does not happen.

I tested this code on macOS as well. Its exactly the same issue! Like it happens in case of "process peer exit", am I not supposed to expect an errored return from boost::asio::async_read also when/if wifi is turned off? The explanation in keep_alive states that it works even when the kernel on server side crashes. Am I missing some more properties to be set on my tcp socket?

来源:https://stackoverflow.com/questions/58696319/tcp-keep-alive-does-not-work-if-you-switch-off-wifi-to-cause-an-abrupt-connectio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!