LINUX.ORG.RU

И снова socket-ы ;-)


0

0

Итак, банальная избитая тема... Но меня как-то поразил эффект. Расскажите на какие настройки сокетов мне глядеть...

А ситуация такая:
- клиент и сервер на разных машинах. Связаны потоковым соединением. На сервере неблокируемый send(), на клиенте блокируемый read().

- Вырываем шнурок из любой машины => соединение на клиенте засыпает, сервер через некоторое время соединение закрывает совсем (смотрю netstat-ом и socklist-ом).

- Вставляем шнурок. И тут начинается самое интересное... Иногда клиент "понимает", что сеодинение закрыто на серверной стороне -- тогда все ок -- завершение, переконнект и победа. Иногда он продолжает упорно висеть в recv()... И вышеупомянутый netstat твердо уверен, что соединение существует! ;\


А если клиент ничего не шлет, то откуда он узнает, что произошел разрыв соединения? После первого пакета посланного серверу сервер скажет RSET и socket на клиенте навернется.

Если хотите форсировать такой форс-мажор - устанавливайте KEEPALIVE опцию на клиенте (да и на сервере).

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

А-абьясняю... Клиент ничего не шлет, зато он принимает... А при recv-е ежели вторая сторона завершила соединение, то возвращается нуль, нуль, еще раз нуль и ничего кроме нуля... ;) (я про линух)

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

А в чем вопрос то заключается? Ну обнаруживается смерть соединения - recv начинает выдавать 0 байт. Ну не обнаруживается, тогда он висит.

Выставьте KEEPALIVE и будет обнаруживать. Без KEEPALIVE и не должен обнаруживать. Вопрос нормально сформулируйте, ок?

Murr ★★
()

keepalive сработает через час! Лучше открыть отдельное соединение и отдельным тредом через промежутки времени посылать сообщения-пульсы. Можно и без еще одного коннекта. Просто пусть поток данных будет состоять из пакетов переменной длины. В заголовке указывается длина пакета и тип. Будет два варианта пакетов - обычные данные и пульсы. Потом просто проверять сколько времени нет пульса. Если очень долго, то отключаться. Проверять время можно select() или poll()

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

KEEPALIVE сработает как поставишь - SOL_TCP опции просто надо раз и навсегда заботать, по умолчанию через 2 часа (умолчание меняется через echo 1> /proc/sys/net/ipv4/tcp_keepalive*). Писать отдельную нить для того, что уже давно придумано и реализовано - это занадто.

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

Вы абсолютно правы дорогой сер. Именно рантаймовые параметры ядра я и поменял. Простите за беспокойство еще вчера доперло... ;)

А по умолчанию таймаут (в красной шапке) выставлен на аж 3-и часа... ;) Да и интеревал между сообщениями -- 72 секунды. ;)

tarle
() автор топика

OxiD>> Исключительно правильный подход... Где-то я это читал... А к параметрам ядра доступ не всегда имеется...

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