#tcp #передача_данных #сетевое_программирование
При работе сетевого приложения сервер-клиент может произойти обрыв кабеля или его вытащат на клиенте. TCP протокол никак не реагирует на это событие, иногда даже ОС не сразу показывает, что кабель отключен. Мое приложение работает почти в реальном времени и пользователь должен знать, что соединение прервалось. Как в приложении определить, что канал связи перестал работать?
Ответы
Ответ 1
Протокол TCP по модели OSI отделен от физической среды передачи, потому ему не нужно знать, что там произошло. Не поможет просто периодически записывать пустой пакет в сокет, операция send просто копирует данные в буфер ОС, а ОС сама их уже отправляет. При этом если с первого раза не дошло TCP отправляет еще несколько раз (до 15), в итоге о том что отправка не удалась вы узнаете через 5 минут или чуть раньше. Я решил этот вопрос на уровне протокола приложения. Эти решения предназначены только для обработки случая с потерей связи на физическом уровне. Вариант 1 "Клиент-маяк" Это случай, когда клиенту не важно работает сервер или нет, и установкой соединения управляет сервер. Сервер сам подключает своих клиентов и решает, когда разорвать соединение. Проверка реализована на стороне сервера. На сервере: Подключиться к клиенту. Принять сообщение "пакет жизни" или другое сообщение от клиента. Установить время для таймера ожидания следующего сообщения 4 сек. Проверять истекло ли время ожидания или пришло сообщение. 4.1. Если Время истекло, то разорвать соединение с клиентом принудительно (считаем нет связи). 4.2. Если пришло сообщение, то шаг 3. На клиенте: Установить соединение к серверу. Отправлять "пакеты жизни" каждые 2 сек без ожидания ответа. Вариант 2 "Взаимный активный контроль" Если нужно оперативно реагировать на отсутствие связи и это два равноправных узла взаимодействующие по каналу связи, например видеозвонок между абонентами. В этом случае каждый из участников выполняет мониторинг состояния соединения самостоятельно. Используется активный периодический опрос. На каждой стороне: Установить соединение с ответной стороной. Отправить запрос PING, установить время ожидания для таймера ответа 4 сек. Проверять наличие ответа и окончание времени ожидания ответа. 3.1 Если пришел ответ PONG или сообщение, то сбросить таймер ожидания ответа, затем подождав 2 сек выполнить шаг 2. 3.2 Если время истекло, то разорвать соединение принудительно (считаем нет связи). Второй участник выполняет мониторинг таким же образом. Вариант 3 (упрощенный вариант 2, активный контроль) Если один из участников сервер и все клиенты подключаются к нему. Протокол приложения должен поддерживать модель "запрос-ответ". В этом случае только клиенты всегда подключаются к серверу. На клиенте: Подключиться к серверу. Выполнить запрос PING, установить время ожидания для таймера ответа 4 сек. Проверять наличие ответа и окончание времени ожидания ответа. 3.1. Если Время истекло, то разорвать соединение принудительно (считаем нет связи). 3.2. Если пришло сообщение, то подождать 2 сек, затем шаг 3. На сервере: Принять соединение клиента. Ожидать 4 сек получения запросов от клиента. Если запрос получен, то шаг 2. Если время ожидания вышло, то разорвать соединение принудительно (считаем нет связи).
Комментариев нет:
Отправить комментарий