АЕ>Авторы: АЕ> Андрей Елсуков
АЕ>Аннотация: АЕ>В статье рассматривается один из способов контроля над работоспособностью TCP/IP-соединения под Windows – создание keep-alive таймера.
Маленькое дополнение: в .NET эти функции обернуты в Socket.IOControl и Socket.SetSocketOption.
АЕ>Авторы: АЕ> Андрей Елсуков
АЕ>Аннотация: АЕ>В статье рассматривается один из способов контроля над работоспособностью TCP/IP-соединения под Windows – создание keep-alive таймера.
А что происходит при определении разрыва соединения? Применяется какой-то асинхронный механизм уведомления или что?
Я так понимаю, если какой-то поток блокирован на recv() на этом сокете, то при разрыве соединения он отвалится с кодом возврата -1. А вот если никто не блокирован на recv(), то что?
АЕ>Авторы: АЕ> Андрей Елсуков
АЕ>Аннотация: АЕ>В статье рассматривается один из способов контроля над работоспособностью TCP/IP-соединения под Windows – создание keep-alive таймера.
сколько запросов посылается при отсутсвии ответа на keep-alive? то есть после того как пропала связь через какое время прийдет сообщение FD_CLOSE?
Здравствуйте, Аноним, Вы писали:
А>сколько запросов посылается при отсутсвии ответа на keep-alive? то есть после того как пропала связь через какое время прийдет сообщение FD_CLOSE?
Спецификация Keep-Alives описана в секции 4.2.3.6 of RFC 1122 (http://rfc.net/rfc1122.html#p101), однако не все провайдеры следуют ей. Например (из RFC 1122):
Keep-alive packets MUST only be sent when no data or acknowledgement packets have been received for the connection within an interval.
Тем не менее TCP стек Windows (проверено в Windows XP SP2) реализует это таким образом: если после начала посыла Keep-Alives (как результата отсутствия входящих пакетов, включая acks, в течение KEEP_ALIVE_TIME), однако до достижения максимального значения неподтвержденных Keep-Alive ретрансмиссий (то есть когда связь считается инвалидной) TCP стек ретрансмитит недошедший пакет, то Keep-Alive процесс начинается сначала. Так как интервал между ретрансмиссиями с каждыи разом растет (см. алгоротм в RFC 2998), у Keep-Alive-а с каждым разом повышается шанс втиснуться и между ретрансмиссиями данных, то есть успеть отработать в отведенное ему время равное KEEP_ALIVE_TIME + KEEP_ALIVE_INTERVAL* KEEPALIVE_PROBES и сообщить о разрыве связи. Куда хуже обстоят дела у стека Linux (проверял для 2.6.5): как только стек начал ретрансмиссию неподтвержденных данных, Keep-Alive уже не включится вне зависимости от интервала между ретрансмиссиями.
Как следствие, в Linux-е Keep-Alive имеет смысл использовать только если интервалы между записью в сокет больше чем KEEP_ALIVE_TIME + KEEP_ALIVE_INTERVAL* KEEPALIVE_PROBES. При большей частоте посылки Keep-Alives просто не будут иметь смысла. Таким образом стек Linux расчитывает на retransmission limit для определения разрыва связи.
Количество неудачных попыток, после которого соединение считается невалиндым, можно устанавливить в Win32 только глобально-системно (хранится в HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters, параметр TcpMaxDataRetransmissions (значение по умолчанию = 5); для оставшихся параметров уже есть возможность устанавки для каждого соединения индивидуально через ::WSAIoctl). В Linux все keep-alive параметры можно устанавливать индивидуально для каждого соединения через setsockopt.
-- Андрей
Re[3]: Определение разрыва TCP-соединения
От:
Аноним
Дата:
28.10.06 15:46
Оценка:
Здравствуйте, Андрей Коростелев
То есть получается, что после того как прошло время, равно KEEP_ALIVE_TIME и за это время никаких данные не передавалось и не принималось посылается keep-alive пакет и если в течении KEEP_ALIVE_INTERVAL интервала ответа на keep-alive пакет не поступилу соединение признается инвалидным. так?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Андрей Коростелев А>То есть получается, что после того как прошло время, равно KEEP_ALIVE_TIME и за это время никаких данные не передавалось и не принималось посылается keep-alive пакет
Почти. Если данные не принимались и не было отослано ни одного подтвержденного пакета.
А> и если в течении KEEP_ALIVE_INTERVAL интервала ответа на keep-alive пакет не поступилу соединение признается инвалидным. так?
Соединение признается инвалидным по прошествию KEEPALIVE_PROBES безответных посылок keep-alive пакета с интервалом между посылками KEEP_ALIVE_INTERVAL.
-- Андрей
Re[5]: Определение разрыва TCP-соединения
От:
Аноним
Дата:
28.10.06 16:19
Оценка:
Здравствуйте, Андрей Коростелев, Вы писали:
АК>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, Андрей Коростелев А>>То есть получается, что после того как прошло время, равно KEEP_ALIVE_TIME и за это время никаких данные не передавалось и не принималось посылается keep-alive пакет
АК>Почти. Если данные не принимались и не было отослано ни одного подтвержденного пакета.
то есть если никакие данные не передавались длительное время и на последний пакет с данными пришло подтверждение то keep-alive пакет не посылается?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Андрей Коростелев, Вы писали:
АК>>Здравствуйте, Аноним, Вы писали:
А>>>Здравствуйте, Андрей Коростелев А>>>То есть получается, что после того как прошло время, равно KEEP_ALIVE_TIME и за это время никаких данные не передавалось и не принималось посылается keep-alive пакет
АК>>Почти. Если данные не принимались и не было отослано ни одного подтвержденного пакета.
А>то есть если никакие данные не передавались длительное время и на последний пакет с данными пришло подтверждение то keep-alive пакет не посылается?
Просто отсчет KEEP_ALIVE_TIME начнется заново.
-- Андрей
Re[7]: Определение разрыва TCP-соединения
От:
Аноним
Дата:
28.10.06 16:34
Оценка:
Здравствуйте, Андрей Коростелев, Вы писали:
АК>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, Андрей Коростелев, Вы писали:
АК>>>Здравствуйте, Аноним, Вы писали:
А>>>>Здравствуйте, Андрей Коростелев А>>>>То есть получается, что после того как прошло время, равно KEEP_ALIVE_TIME и за это время никаких данные не передавалось и не принималось посылается keep-alive пакет
АК>>>Почти. Если данные не принимались и не было отослано ни одного подтвержденного пакета.
А>>то есть если никакие данные не передавались длительное время и на последний пакет с данными пришло подтверждение то keep-alive пакет не посылается?
АК>Просто отсчет KEEP_ALIVE_TIME начнется заново.
Ну, предположим что нам ничего не шлют и на последний отосланный пакет пришло подтверждение, тогда с этого момента начинается новый отсчет KEEP_ALIVE_TIME. по истечении которого посылается keep-alive пакет так?
а что будет если на последний отосланный пакет не пришло подтверждение?
Здравствуйте, Аноним, Вы писали:
А>Ну, предположим что нам ничего не шлют и на последний отосланный пакет пришло подтверждение, тогда с этого момента начинается новый отсчет KEEP_ALIVE_TIME. по истечении которого посылается keep-alive пакет так?
Именно так.
А>а что будет если на последний отосланный пакет не пришло подтверждение?
Keep-alive таймер взводится начиная с последнего пришедшего пакета (в т.ч. ack-a на отправленный). Если таковых еще не было (приложение еще не получало не передавало никаких данных, которые были подтверждены), то это время отсчитывается от начала установки соединения (входящий syn+ack для активного открытия или входящий ack для пассивного открытия соединения).
Все извини, пошел пить пиво, если еще вопросы — отвечу не раньше понедельника.
-- Андрей
Re[9]: Определение разрыва TCP-соединения
От:
Аноним
Дата:
28.10.06 16:56
Оценка:
Здравствуйте, Андрей Коростелев, Вы писали:
АК>Все извини, пошел пить пиво, если еще вопросы — отвечу не раньше понедельника.
Да нет, все ясно... я так чисто, уточнить... спасибо большое.
АЕ>Авторы: АЕ> Андрей Елсуков
АЕ>Аннотация: АЕ>В статье рассматривается один из способов контроля над работоспособностью TCP/IP-соединения под Windows – создание keep-alive таймера.
наследуются ли эти установки в сокетах? например такой код
sok = socket(...);
WSAIoctl(sok, ...);
sok2 = accept(sok, ...);
на sok2 будет распространяться установка keep-alive? или же у него все будет по умолчанию и прийдется вызывать WSAIoctl?
АЕ>Авторы: АЕ> Андрей Елсуков
АЕ>Аннотация: АЕ>В статье рассматривается один из способов контроля над работоспособностью TCP/IP-соединения под Windows – создание keep-alive таймера.
а почему рассмотрен только виндовс?
Posix.1g расписывает как установить время до первой проверки и периодичность.
это setsockopt, уровень IPPROTO_TCP, параметры:
— TCP_KEEPALIVE — время до первой проверки, по умолчанию 2 часа
— TCP_MAXRT — периодичность проверок при отсутствии ответов, по умолчанию 75 сек
всего проверок 9.
однако не расписывается, как должны применяться эти параметры, и разные ядра реализуют разное поведение, иногда просто не реализуют
нужно быть готовыми к тому, что настройки буду задействованы для всех сокетов со включенным SO_KEEPALIVE, несмотря на указание сокета