Сценарий.
У меня есть клиент и сервер, написанные с использованием boost::asio 1.63. В целом связь и коммуникационная часть работают хорошо и отлично.
Я написал Watchdog с обеих сторон, которые отправляют фиктивные пакеты партнерам с интервалом в 2 секунды каждый. Цель сторожевого таймера состоит в том, чтобы заинтересованный одноранговый узел сообщал об ошибке соединения, если он не получил фиктивный пакет, который ожидал в течение следующих 2 секунд. Это еще более важно для меня, потому что может случиться так, что 2 одноранговых узла не передают пакеты для какой-либо пользовательской цели, но каждый из них должен сообщать об ошибке соединения, если какой-либо из одноранговых узлов выходит из строя. Одноранговый узел может выйти из строя даже из-за сбоя ядра, и в этом случае этот одноранговый узел не сможет отправить сообщение. Конечно, это классическая проблема, которая существует даже за пределами asio и TCP.
Мой Watchdog работает отлично. Никаких проблем.
Но недавно я прочитал о keep_alive в сокетах. Я попробовал следующий код и, похоже, я могу использовать свойство keep_alive в сокете TCP, получив собственный дескриптор сокета из моего кода, используя 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));
Вопрос.
Приведенный выше код хорошо компилируется в macOS, Linux и iOS. Это выглядит великолепно. Но какая мне от этого польза? Дает ли это мне обратный вызов или событие, когда одноранговый узел выходит из строя? Освобождает ли это меня от написания Watchdog, о котором я говорил выше?
Я использовал boost::asio::async_connect
для подключения к узлу. Могу ли я получить обратный вызов моему обработчику соединений, когда perr выходит из строя после определенного интервала времени ожидания?
Установив параметры keep_alive
, как мне тогда узнать, что мой пир больше не отвечает?
setsockopt
, вы можете использоватьmySocket.set_option
- person tkausl   schedule 04.11.2019Does this give me a callback or event when the peer goes down?
Я предполагаю, что он не работает с кодом выхода при чтении и записи. - person tkausl   schedule 04.11.2019It wouldn't send me an event if my peer is sitting idle and not doing any read/write.
Верно, но когда это произойдет? Обычно у вас всегда есть чтение, ожидающее данных, не так ли? - person tkausl   schedule 04.11.2019asyc_read
и бесконечныйasyc_write
с обеих сторон, что я и делаю :-). Тогдаasyc_read
/asyc_write
вернется с ошибкой, как только будет обнаружено, что одноранговый узел не работает? Не могли бы вы подтвердить? Если это так, то я счастлив и попробую это на своем коде, чтобы увидеть, работает ли он. Вы можете опубликовать это как ответ, если это действительно так. - person AdeleGoldberg   schedule 04.11.2019Correct, but when would this happen? You'd usually always have a read waiting for data, no?
Да. Я делаю. У меня есть async_read, всегда ожидающий данных. Я должен был сделать что-то неправильно в значениях времени ожидания. Тогда я должен получить обратный вызов с ошибкой на моемasync_read
? - person AdeleGoldberg   schedule 04.11.2019