Сценарий:
У меня есть клиент и сервер, написанные с использованием boost :: asio 1.63 . Я использую функцию keep_alive в сокетах tcp для обнаружения потери соединения.
Ниже приведена настройка кода 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(), 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
У меня есть boost::asio::async_read
с обеих сторон, всегда ожидающих данных. Он возвращает ошибку, когда другой узел выходит. Следовательно, потеря соединения обнаружена. Эта логика хорошо работает как на Linux на стороне сервера, так и на Android на стороне клиента.
Вопрос:
ЕслиЯ правильно покидаю одноранговый узел, нажимая кнопку «Закрыть», и все работает хорошо. Если я отключу Wi-Fi на моем Android-устройстве, то через 2 секунды я получу сообщение об ошибке. Но , этого не происходит.
Я также тестировал этот код на macOS. Это точно такая же проблема! Как это происходит в случае « выхода из процесса », разве я не должен ожидать ошибочного возврата от boost::asio::async_read
также, когда / если Wi-Fi выключен? Объяснение в keep_alive гласит, что оно работает, даже когда ядро на стороне сервера падает. Мне не хватает еще нескольких свойств, которые нужно установить в моем сокете tcp?