2016-11-05 9 views
1

У меня есть несколько вопросов, связанных с keep_alive.keep_alive опции для усиления tcp-приемника и усиления tcp-сокета

  • В чем разница между basic_socket_acceptor::keep_alive и basic_stream_socket::keep_alive? Когда использовать какой?
  • Нужно ли использовать любые keep_alive для ip::tcp::acceptor? Для меня это не имеет смысла, так как есть no соединение как таковое для акцептора, но есть keep_aliveвариант для него также, следовательно, путаница.
  • Если установлено keep_alive, то каково поведение Boost Asio при обнаружении неисправного соединения? Как/когда он уведомляет пользовательский код? Вызывает ли это исключение? Если да, то какое исключение? Я не вижу таких подробностей в документации.

ответ

2

В чем разница между basic_socket_acceptor :: keep_alive и basic_stream_socket :: keep_alive? Когда использовать какой?

Оба эти же. В документации это отображается под basic_socket_acceptor и basic_stream_socket, потому что оба они производны от socket_base, в которых опция keepalive фактически видна (это typedef).

В соответствии, например, в документации, вы всегда будете использовать его как:

boost::asio::socket_base::keep_alive option(true); 
socket.set_option(option); 

мы должны использовать любой вид keep_alive для IP :: Tcp :: акцептора ли?

Нет, вам это не обязательно, и вы не можете. set_option anyways может быть вызван только на объект сокета (я считаю, что только после сокета opened).

Если установлено keep_alive, то каково поведение Boost Asio, когда оно обнаруживает поврежденное соединение?

Это зависит от платформы. На linux вы получите broken pipe ошибки или EPOLLERR/EPOLLHUP, когда сбой датчика keep_alive.

UPDATE (от моего комментария ниже):

Эта неудача не распространяется на код пользователя. Таким образом, возможно, вам нужно реализовать пинг на уровне приложения или использовать опцию тайм-аут.

+1

* «В Linux вы будете получать сломанную ошибку трубы или EPOLLERR/EPOLLHUP когда keep_alive зонда выходит из строя.» *. Как бы ** I ** (то есть пользовательский код) получить что-либо, если я не * явно * отправлю любые пакеты keepalive? Я полагаю, что после установки опции 'keep_alive', базовая библиотека отправляет такие пакеты клиентам, и я, вероятно, не знаю, когда и как часто это происходит. Какими бы ни были ответы на эти вопросы, моя единственная забота - это то, как именно он уведомляет пользователя, когда он видит * сломанный трубопровод *? Нужно ли мне устанавливать любой обратный вызов, который будет вызывать библиотека? – Nawaz

+0

Oh..ok. На самом деле отправка и прием сохраненных зондов осуществляется ОС и контролируется параметрами 'sysctl' в linux. Таким образом, даже если вы установите параметр keepalive в сокете вашего кода, это не означает, что ОС отправит пробники. Вам нужно явно включить его через 'procfs' или' sysctl', и пока вы на нем, вы даже можете настроить таймер для отправки зондов keepalive. – Arunmu

+0

«Моя единственная забота заключается в том, как именно он уведомляет пользователя о том, что он видит сломанный трубопровод? Мне нужно установить любой обратный вызов, который будет вызывать библиотека?» Вы правы, я не прошел полную реализацию. Этот отказ не распространяется на код пользователя. Таким образом, возможно, вам нужно выполнить пинг на уровне приложения или использовать опцию сокета 'timeout'. – Arunmu

1

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 на операции записи. Следовательно, базовая система возвратит с соответствующей ошибкой

 Смежные вопросы

  • Нет связанных вопросов^_^