basic_socket_acceptor::keep_alive
и basic_stream_socket::keep_alive
такие же. В документации отмечается, что они оба наследуются от класса socket_base
, который определяет опцию socket_base::keep_alive
.
basic_stream_socket::keep_alive
унаследованные от socket_base.
Опция Socket для отправки keep-alives.
В то время как сохранение в прослушивающем сокете непосредственно не полезно для прослушивающего сокета, в некоторых системах вновь принятый сокет наследует некоторые параметры сокета из прослушивающего сокета. Унаследованные параметры сокета - это, как правило, параметры, которые влияют на трехстороннее рукопожатие TCP, которое должно завершиться до возврата accept()
, например SO_KEEPALIVE
. Следовательно, Asio поддерживает настройку опции keep-alive на акцепторе; однако Asio не копирует параметры сокета в новый сокет.
Держать-жива функция позволяет написать операции должны быть уведомлены о том, что соединение сломано, как определено Keep-Alive механизм . Следовательно, когда зонд keep-alive не работает, следующая операция записи Asio на сокете завершится с ошибкой , передав error_code
в приложение таким же образом, как и другие коды ошибок. Следует обратиться к документации по операционной системе, чтобы определить ожидаемый код ошибки операции записи:
- В Windows
WSASend()
документирован как возвращение WSAENETRESET
(boost::asio::error:: connection_reset
)
- На Linux, ошибка будет варьироваться в зависимости от того, как зонд keep-alive не работает. Если ответов нет, то произойдет
ETIMEOUT
(boost::asio::error::timed_out
). Если ICMP-ошибка возвращается в ответ на запрос keep-alive, тогда вместо этого будет возвращена соответствующая ошибка ICMP. Например, можно было наблюдать EHOSTUNREACH
(boost::asio::error::host_unreachable
) возвращается
1. См 4.2.3.6 на Требования, предъявляемые к Интернет Хосты-коммуникационных слоев указанных в RFC 1122
2. SO_KEEPALIVE
оповещает нить записывая в сокет через сигнал SIGPIPE
, но Asio явно отключает прием SIGPIPE
на операции записи. Следовательно, базовая система возвратит с соответствующей ошибкой
* «В Linux вы будете получать сломанную ошибку трубы или EPOLLERR/EPOLLHUP когда keep_alive зонда выходит из строя.» *. Как бы ** I ** (то есть пользовательский код) получить что-либо, если я не * явно * отправлю любые пакеты keepalive? Я полагаю, что после установки опции 'keep_alive', базовая библиотека отправляет такие пакеты клиентам, и я, вероятно, не знаю, когда и как часто это происходит. Какими бы ни были ответы на эти вопросы, моя единственная забота - это то, как именно он уведомляет пользователя, когда он видит * сломанный трубопровод *? Нужно ли мне устанавливать любой обратный вызов, который будет вызывать библиотека? – Nawaz
Oh..ok. На самом деле отправка и прием сохраненных зондов осуществляется ОС и контролируется параметрами 'sysctl' в linux. Таким образом, даже если вы установите параметр keepalive в сокете вашего кода, это не означает, что ОС отправит пробники. Вам нужно явно включить его через 'procfs' или' sysctl', и пока вы на нем, вы даже можете настроить таймер для отправки зондов keepalive. – Arunmu
«Моя единственная забота заключается в том, как именно он уведомляет пользователя о том, что он видит сломанный трубопровод? Мне нужно установить любой обратный вызов, который будет вызывать библиотека?» Вы правы, я не прошел полную реализацию. Этот отказ не распространяется на код пользователя. Таким образом, возможно, вам нужно выполнить пинг на уровне приложения или использовать опцию сокета 'timeout'. – Arunmu