UNIX: разработка сетевых приложений
Шрифт:
Когда на сокете происходит ошибка, модуль протокола в ядре, происходящем от Беркли, присваивает переменной
1. Если процесс блокируется в вызове функции
2. Если процесс использует управляемый сигналом ввод-вывод (см. главу 25), для него или для группы таких процессов генерируется сигнал
Процесс может получить
Если процесс вызывает функцию
В коде, показанном на с. 495 [128], есть ошибка: so_error не сбрасывается в 0. Она была выявлена в реализации BSD/OS. Всегда, когда для сокета возвращается ошибка, требующая обработки, so_error должна быть сброшена в 0.
Здесь вы впервые встречаетесь с параметром сокета, который можно получить, но нельзя установить.
Параметр сокета SO_KEEPALIVE
Когда параметр
1. Собеседник отвечает, присылая ожидаемый сегмент ACK. Приложение не получает уведомления (поскольку все в порядке). TCP снова отправит одно проверочное сообщение еще через два часа отсутствия активности в этом соединении.
2. Собеседник отвечает, присылая сегмент RST, который сообщает локальному TCP, что узел собеседника вышел из строя и перезагрузился. Ошибка сокета, требующая обработки, устанавливается равной
3. На проверочное сообщение не приходит ответ от собеседника. Код TCP, происходящий от Беркли, отправляет восемь дополнительных проверочных сообщений с интервалом в 75 с, пытаясь выявить ошибку. TCP прекратит попытки, если ответа не последует в течение 11 мин и 15 с после отправки первого сообщения.
HP-UX обрабатывает поверочные сообщения так же, как и обычные данные, то есть второе сообщение отсылается по истечении периода повторной передачи, после чего для каждого последующего пакета интервал ожидания удваивается, пока не будет достигнут максимальный интервал (по умолчанию — 10 мин).
Если на все проверочные сообщения TCP не приходит ответа, то ошибка сокета, требующая обработки, устанавливается в
В главе 23 [111] и на с. 828-831 [128] содержатся дополнительные подробности об этом параметре.
Без сомнения, наиболее типичный вопрос, касающийся этого параметра, состоит в том, могут ли изменяться временные параметры (обычно нас интересует возможность сокращения двухчасовой задержки). В разделе 7.9 мы описываем новый параметр
Назначение этого параметра — обнаружение сбоя на узлесобеседника. Если процесссобеседника выходит из строя, его TCP отправит через соединение сегмент FIN, который мы сможем легко обнаружить с помощью функции
Этот параметр обычно используется серверами, хотя его могут использовать и клиенты. Серверы используют его, поскольку большую часть своего времени они проводят в блокированном состоянии, ожидая ввода по соединению TCP, то есть в ожидании запроса клиента. Но если узел клиента выходит из строя, процесс сервера никогда не узнает об этом и сервер будет продолжать ждать ввода данных, которые никогда не придут. Это называется наполовину открытым соединением( half-open connection). Данный параметр позволяет обнаружить наполовину открытые соединения и завершить их.
Некоторые серверы, особенно серверы FTP, предоставляют приложению тайм- аут, часто до нескольких минут. Это выполняется самим приложением, обычно при вызове функции
В SCTP имеется механизм проверки пульса (heartbeat), аналогичный механизму проверочных сообщений (keep-alive) TCP. Этот механизм настраивается при помощи элементов параметра сокета SCTP_SET_PEER_ADDR_PARAMS, который будет описан далее, а не при помощи параметра SO_KEEPALIVE. Последний полностью игнорируется сокетом SCTP и не мешает работе механизма проверки пульса.
В табл. 7.3 суммируются различные методы, применяемые для обнаружения того, что происходит на другом конце соединения TCP. Когда мы говорим «использование функции
Таблица 7.3. Методы определения различных условий TCP
Сценарий | Процесс собеседника выходит из строя | Узел собеседника выходит из строя | Узел собеседника недоступен |
---|---|---|---|
Наш TCP активно посылает данные | TCP собеседника посылает сегмент FIN, что мы можем сразу же обнаружить, используя функцию select для проверки готовности к чтению. Если TCP посылает второй сегмент, TCP собеседника посылает в ответ сегмент RST. Если TCP посылает еще один сегмент, наш TCP посылает сигнал SIGPIPE | По истечении времени ожидания TCP возвращается ошибка ETIMEDOUT | По истечении времени ожидания TCP возвращается ошибка ETIMEDOUT |
Наш TCP активно принимает данные | TCP собеседника посылает сегмент FIN, который мы прочитаем как признак конца файла (возможно, преждевременный) | Мы больше не получаем никаких данных | Мы больше не получаем никаких данных |
Соединение неактивно, посылается пробный пакет | TCP собеседника посылает сегмент FIN, который мы можем сразу же обнаружить, используя функцию select для проверки готовности к чтению | По истечении двух часов отсутствия активности отсылается 9 сообщений для проверки наличия связи с собеседником, а затем возвращается ошибка ETIMEDOUT | По истечении двух часов отсутствия активности отсылается 9 сообщений для проверки наличия связи с собеседником, а затем возвращается ошибка ETIMEDOUT |
Соединение неактивно, не посылается проверочное сообщение | TCP собеседника посылает сегмент FIN, который мы можем сразу же обнаружить, используя функцию select для проверки готовности к чтению | Ничего не происходит | Ничего не происходит |