У вас есть два варианта здесь:
- Реализовать сердцебиения на уровне приложений. Другими словами, вы пишете код, который обнаруживает незанятые соединения и периодически отправляет сообщение уровня приложения, чтобы существенно исследовать соединение и убедиться, что он все еще открыт.
- Используется протокол TCP keepalive. Это в основном сдвигает работу по внедрению и обработке сообщений с сердечным ритмом вплоть до уровня TCP. Это кажется хорошим выбором в вашем случае.
Чтобы включить и настроить протокол TCP keepalive, вам необходимо изменить параметры сокета с помощью setsockopts(2)
. Есть 3 параметра, которые необходимо проверить/изменить:
TCP_KEEPCNT
- это число выдающихся, оставшихся без ответа зондов, которые разрешены в любой момент времени. Если в течение заданного интервала времени отправляются более TCP_KEEPCNT
зондов, соединение считается мертвым.
TCP_KEEPIDLE
- время, в течение которого соединение должно быть простаивающим до начала отправки пакетов-зондов.
TCP_KEEPINTVL
- время между отдельными пробниками.
Таким образом, вы делаете что-то вроде этого на client_fd
:
int tcp_keepcnt = 3;
int tcp_keepidle = 30;
int tcp_keepintvl = 60;
setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPCNT, &tcp_keepcnt, sizeof(tcp_keepcnt));
setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPIDLE, &tcp_keepidle, sizeof(tcp_keepidle));
setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPINTVL, &tcp_keepintvl, sizeof(tcp_keepintvl));
разорванные соединения представлены как читаемый epoll(7)
с EPOLLHUP
флагом. Обратите внимание, что закрытие заказа будет сообщено в читаемом безEPOLLHUP
, но вместо этого read(2)
вернет 0.
Имейте в виду, что обнаружение мертвого соединения не сразу. Это займет некоторое время. Например, с указанными выше параметрами это займет примерно 3 минуты.
Что вы имеете в виду? Я не использовал telnet на стороне сервера. Я также создаю клиентское приложение для замены telnet, но получаю тот же результат. – thanhtv