LINUX.ORG.RU

Epoll ESTABLISHED соединения на сервере


0

1

Здравствуйте!

http://www.opennet.ru/base/dev/epoll_intro.txt.html

Собрал этом пример — сервер и клиент (tester.cpp) — все работает, но если отключить интернет на клиентской машине (где tester.cpp) то все соединения зависают на сервере:

tcp 0 0 213.239.219.253:4444 213.142.143.187:55305 ESTABLISHED tcp 0 0 213.239.219.253:4444 213.142.143.187:55304 ESTABLISHED tcp 0 0 213.239.219.253:4444 213.142.143.187:55307 ESTABLISHED tcp 0 0 213.239.219.253:4444 213.142.143.187:55306 ESTABLISHED tcp 0 0 213.239.219.253:4444 213.142.143.187:55301 ESTABLISHED tcp 0 0 213.239.219.253:4444 213.142.143.187:55300 ESTABLISHED tcp 0 0 213.239.219.253:4444 213.142.143.187:55303 ESTABLISHED …. …. Какие есть алгоритмы для закрытия таких соединений?

Спасибо!

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

Deleted ()

> но если отключить интернет на клиентской машине (где tester.cpp) то все соединения зависают на сервере

пробовал ждать например часа 3? или сколько времени прошло с начало зависания?

ЧАСТЫЕ пинги (которые идут более периодично чем через каждый 2 часа) — ВРЕДЫ.. так как например если клиент сидит в интернете из гаджита, которые работает на батарейках — то тратить электроэнергию батареи на лишнии [частые] пинги — это зло

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

Спасибо! Прождал 3 часа - соединения все также висят, меня бы усторила если бы они даже через 3ч закрывались. Может быть это мне поможет: setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);

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

набросал два тестовых-скрипта (тест-сервер и тест-клиент), использующих epoll и socket

...покачто БЕЗ внесения опции SO_KEEPALIVE в сокеты

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

...пока ещё не заметил :-(

# p.s.: файлы: https://gist.github.com/1366737#file_test_keep_alive_server https://gist.github.com/1366741#file_test_keep_alive_client

user_id_68054 ★★★★★ ()
Ответ на: комментарий от Dark_SavanT

это меня и пугает :-)

в представленом выше документе TCP-Keepalive-HOWTO написанно

«„“ Remember that keepalive support, even if configured in the kernel, is not the default behavior in Linux. Programs must request keepalive control for their sockets using the setsockopt interface. »«»

...вот и решил проверить... неужеле это действительно страшная правда! x_x :-D

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

Почитай RFC связанные с TCP, там про keepalive было, как и когда оно работает.

Dark_SavanT ★★★★★ ()
Ответ на: комментарий от user_id_68054

А, чёрт, туплю. Да линукс по-дефолту не отслеживает состояние соединения. Так что наиболее вменяемым способом получения информации о живости соединения является посылка keepalive пакетов и явное(т.е. клиент сообщает серверу о своём отключении) завершение сессии.

Либо UDP.

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

Да линукс по-дефолту не отслеживает состояние соединения

ну вобщем опытным путём мы выяснили что ДА :-) ... — HOWTO не врёт... :-) :-)

* * * * * * * * * *

пробую вот щаз на сервере версию тэста ( ...#file_test_keep_alive_server_so ; ...#file_test_keep_alive_client_so ) — с добавлением опции SO_KEEPALIVE (пробую вариант когда SO_KEEPALIVE устанавливается только один раз — для bind-сокета, но не для acepted-сокетов... и не для клиентских сокетов :)...)

...интересно в данном опыте узнать — буду ли в этом случае какиенить негативные эффекты... например будут ли обрываться через несколько часов обычные (не «мёрвные») client`ские соеденения через которые НЕ идёт [несколько часов] полезного трафика ни в одну из сторон

user_id_68054 ★★★★★ ()
Ответ на: комментарий от Dark_SavanT

> Да линукс по-дефолту не отслеживает состояние соединения

а кстате — какие ОС/Ядра — отслеживают по умолчанию?

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

> ...интересно в данном опыте узнать — буду ли в этом случае какиенить негативные эффекты... например будут ли обрываться через несколько часов обычные (не «мёрвные») client`ские соеденения через которые НЕ идёт [несколько часов] полезного трафика ни в одну из сторон

по истечению нескольких часов — сервер отключил ВСЕ соеденения («Connection timed out»)... и соеденения которые были «мёртвые» (разрыв ethernet-провода) и соеденения которые были «живые» но безактивные

..я прямо в тупике... чтоже это такое твориться...... а может быть просто маршрутизатор (DLink в режиме NAT) сбойнул — и на самом деле «мёртвые» оказались соеденения ВСЕ, и поэтому они отключились %) %)

...а может быть это стандартное поведение алгоритма Keepalive %) %) %)

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

видимо чтобы точно выяснить — придётся подключаться не с домашего компьютера, а с сервера на сервер....

....чтобы исключить вероятность неправильно работающщего NAT

user_id_68054 ★★★★★ ()
Ответ на: комментарий от Dark_SavanT

не, не, — я уже всё проверил — sock.setsockopt(socket.SOL_SOCKET,socket.SO_KEEPALIVE, 1) — работает очень хорошо и правильно :-)

...и причём досточно выполнить эту команду *только* на *одном* за`bind`инном сокете (а не на каждом сокете который приходит от accept)

единственное слабое звено остаётся — это говно`NAT`устройства... которые не могут осилить два часа НЕ забывать про TCP-сессию :-( ....но такие NAT — не все.. есть и правильные NAT :-)

если уменьшить значение net.ipv4.tcp_keepalive_time (TCP_KEEPIDLE) — до 5 минут... то даже тупые NAT перестают рвать соеденения :-)

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