LINUX.ORG.RU

Как определить обрыв соединения?


0

2

Сервер вызывает accept() на блокирующий сокет и ждёт подключения.

Клиент вызывает connect() чтобы установить соединие, вызывает recv() на блокирующий сокет и ждёт данные.

После этого у сервера пропадает питание, т.е. TCP/IP соединение не закрывается корректно.

Но клиент продалжает висеть на recv().

После того, как сервер по новой вызовет accept(), соединение уже не установится, т.к. клиент должен использовать новый сокет, заново вызвать connect() и т.д.

Как клиент может узнать, что соединение разорвано? Попробовал как написано тут http://stunpix.com/post/socket-closed-detection/ , но poll() после обрыва возвращает 0, видимо из-за некорректного завершения соединения.


ждать, пока таймаут пройдёт

либо периодически гонять по соединению пинги, если оно отвалилось, то обрыв обнаружится раньше

Harald ★★★★★ ()

Уровнем выше tcp реализуешь свой протокол, в котором вводишь сообщения типа ping-pong с нужным тебе таймаутом, в течении которого считаешь, что соединение не разорвано. А далее как тебе хочется, например, при разрыве непрерывно пытаешься переконнектиться к северу, а на сервере listen

Deleted ()

alarm(toomuch), либо городить хартбит, либо объяснить себе зачем это ненужно.

arturpub ★★ ()

Вроде как была какая-то константа, TCP_KEEP_ALIVE или что-то типа того, которую можно было установить для соединения. Работает так: если в течении TCP_KEEP_ALIVE секунд по соединению не пришло информации от сервера, то посылается специальный пакет. Если на него с той стороны никто не ответит - соединение разрывается.

Лучше почитать подробности в манах.

g0t0 ()

Никак. После обрубания питания, клиент может попытаться послать данные, тогда сработает логика tcp и придется немного подождать. Очень быстрый способ: слать icmp пакеты на сервак, тогда будут приходить точные ответы с информацией о состоянии соединения.

gh0stwizard ★★★★★ ()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от Deleted

Почему это? Насколько мне известно, эта фича как раз для того и нужна, чтобы задетектировать обрыв соединения (вместо того, чтобы самому велосипеды городить). Правда, дефолтное значение интервала там - два часа, поэтому нужно при помощи setsockopt выставить нормальные значения для таймеров

anonymous ()
Ответ на: комментарий от anonymous

2 часа там неспроста. Это небольшой штатный костыль.

Implementors MAY include «keep-alives» in their TCP implementations, although this practice is not universally accepted. If keep-alives are included, the application MUST be able to turn them on or off for each TCP connection, and they MUST default to off. (c) rfc1122

Идеологически, tcp-соединение подразумевает возможность рваться сколь угодно много и долго нижележащим уровням, а keep-alive слегка противоречит этому, но облегчает задачу сбора мусора системой, и обычно не мешает (например, ssh соединение на суспенженом ноутбуке чаще всего сохраняется). Если программисту необходимо явное информирование о достижении данных адресату в заданный интервал времени - это программируется явно, с помощью техники пинг-понг.

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Угу. И ее можно настроить, что как раз позволяет получать разрыв соединения при длительном молчании другой стороны.

g0t0 ()
Ответ на: комментарий от g0t0

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

Deleted ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.