Pull to refresh

Comments 14

Насколько я помню, как минимум под Linux вечно соединение без данных жить не будет.
Оно схлопнется, когда истечет параметр net.netfilter.nf_conntrack_tcp_timeout_establishe (по умолчанию: через 5 суток).

Так же есть еще SO_KEEPALIVE и SO_RCVTIMEO. Тогда соединение вообще будет вести себя предсказуемо, без гиганских задержек.

Я бы не стал полагаться на SO_KEEPALIVE. Там таймаут порядка 2-х часов.
В моей практике был прецедент: между серверами, которые держали неактивное соединение, находился statefull firewall и через час данные переставали через него проходить, хотя формально с обоих сторон соединение открыто.

Ну по дефолту действительно 2 часа:


cat /proc/sys/net/ipv4/tcp_keepalive_time

7200


cat /proc/sys/net/ipv4/tcp_keepalive_intvl

75


cat /proc/sys/net/ipv4/tcp_keepalive_probes

9


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

так это проблема не серверов, а настройки фаерволла. У любого нормально fw есть механизм dead connection detection, специально для того, чтоб не разрушать длинные tcp-сессии в которых бывают большие периоды без передачи
UFO just landed and posted this here
Сломанные трубы в ssh хорошо помогают понять что такое rst и когда его присылают.

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

Вроде все правильно написано, но с другой стороны зачем? Классическая книга Ричарда Стивенса, изданная в 1994 году, покрывает эти и еще многие другие случаи гораздо подробнее и с детальным анализом tcpdump. Да она и написана интереснее на мой вкус.
Я надеялся увидеть обзор новых фишек TCP, которых с тех пор появилось множество и которые нигде систематически не описаны, но увы...

Во втором издании Стивенса много новых фишек
Так вот почему у меня так странно себя qutim вёл. Про обрыве соединения (подозреваю, там физически болтался контакт и система постоянно переустанавливала соединение) джаббер позволял отправлять сообщение, однако они никуда не приходили. И сообщений об ошибке тоже не было.
TCP придуман как раз затем, чтобы абстрагироваться от проблем среды передачи данных, и диагностировать при его использовании подобные аппаратные проблемы очень непросто. Если вам нужно оперативно реагировать на такие вещи, лучше использовать UDP.
Даже если нет данных для отправки, каждый участник TCP-соединения обязан регулярно слать подтверждения своей готовности принять данные (т.е. сведения о состоянии окна приёма). Если вторая сторона долго не подтверждает готовность принять данные — надо послать ей «нулевые данные» (т.е. пакет как бы с данными, но размер данных равен нулю).; и тогда та сторона обязана подтвердить приём данных. А если не подтвердила (ну, надо убедиться, послав несколько раз) — то надо убивать сессию на своей стороне.
> обязан регулярно слать подтверждения своей готовности принять данные (т.е. сведения о состоянии окна приёма).

Только при изменении этого окна.

> надо послать ей «нулевые данные»

«Нулевые данные» невозможно послать средствами уровня сокетов. И противоположная сторона не обязана это подтверждать (она воспринимает такое просто как дежурный ACK). Единственный гарантированный способ получить ответ другой стороны — послать реальные данные.

В случае TCP — только на уровне сессии можно это лечить надёжно и кроссплатформенно (keepaliveʼами протокола уже выше уровнем, нежели TCP, тогда можно вводить собственный таймаут).
Снова обратите внимание — это истёкший тайм-аут read. Мы бы увидели ту же самую ошибку и при других операциях с сокетом. Это происходит потому, что сокет входит в состояние, когда истёк тайм-аут подключения. Причина этого в том, что удалённая сторона слишком долго не подтверждала пакет данных — 5 минут, в соответствии с настройками этой системы.

Где-то здесь будет повторная отправка данных с увеличивающимся интервалом (обычно интервал удваивается).
За этим лучше наблюдать не только по системным вызовам, но и по tcpdump.

Sign up to leave a comment.