Boost:: asio:: ip:: tcp:: socket подключен?

Я хочу проверить статус соединения, прежде чем реализовать свои операции (чтение/запись).

Есть ли способ сделать метод isConnect()?

Я видел этот, но он кажется "уродливым".

Я тестировал is_open() также, но не имеет ожидаемого поведения.

Ответы

Ответ 1

TCP должен быть надежным перед жесткой сетью; даже несмотря на то, что TCP обеспечивает то, что выглядит как постоянное сквозное соединение, все это просто ложь, каждый пакет - действительно просто уникальная ненадежная датаграмма.

Соединения - это действительно просто виртуальные кабели, созданные с небольшим состоянием, отслеживаемым на каждом конце соединения (исходные и целевые порты и адреса и локальный сокет). Сетевой стек использует это состояние, чтобы узнать, какой процесс должен предоставлять каждый входящий пакет и какое состояние помещать в заголовок каждого исходящего пакета.

Virtual TCP Conduit

Из-за базового — по своей сути бесконтактный и ненадежный; характер сети, стек будет сообщать только о отключенном соединении, когда удаленный конец отправляет FIN-пакет для закрытия соединения или если он не получает ответ ACK на отправленный пакет (после таймаута и повторной попытки пары).

Из-за асинхронного характера asio самый простой способ получить извещение об изящном отключении - иметь выдающийся async_read, который вернет error::eof сразу же после закрытия соединения. Но это одно по-прежнему оставляет возможность других неполадок, таких как полуоткрытые соединения и проблемы с сетью, которые остаются незамеченными.

Самый эффективный способ обхода неожиданного прерывания соединения - использовать какой-то режим keep-alive или ping. Эта случайная попытка передачи данных по соединению позволит эффективно обнаруживать непреднамеренно разъединенное соединение.

Протокол TCP фактически имеет встроенный механизм keep-alive, который можно настроить в asio с помощью asio::tcp::socket::keep_alive. Самое приятное в том, что TCP keep-alive заключается в том, что он прозрачен для приложения с пользовательским режимом, и только его коллеги, заинтересованные в поддержке, должны настроить его. Недостатком является то, что вам нужен доступ/знания уровня ОС для настройки параметров тайм-аута, они, к сожалению, не подвергаются простой опцией сокета, и обычно имеют значения таймаута по умолчанию, которые довольно велики (7200 секунд в Linux).

Вероятно, наиболее распространенным методом keep-alive является его реализация на уровне приложения, где приложение имеет специальное сообщение noop или ping и ничего не реагирует, когда его щекочет. Этот метод дает вам максимальную гибкость при реализации стратегии keep-alive.

Ответ 2

TCP promises, чтобы наблюдать за упавшими пакетами - при необходимости повторите попытку, чтобы дать вам надежное соединение, для некоторого определения надежного. Конечно, TCP не может обрабатывать случаи, когда сервер выходит из строя, или ваш кабель Ethernet выпадает или что-то подобное происходит. Кроме того, зная, что ваше TCP-соединение работает, не обязательно означает, что протокол, который будет проходить через TCP-соединение, готов (например, ваш веб-сервер HTTP или ваш FTP-сервер может находиться в некотором сломанном состоянии).

Если вы знаете, что протокол отправляется через TCP, вероятно, есть способ в этом протоколе сказать вам, если все в хорошей форме (для HTTP это будет HEAD)

Ответ 3

вы можете отправить фиктивный байт в сокет и посмотреть, не вернет ли он ошибку.