2015-07-09 2 views
0

Я протестированные epoll в случае сетевого кабеля отсоединил:Обнаружение сетевого кабеля Unplugged ошибки с Epoll

  • сервер открывает порт 3000
  • создать Epoll и добавить server_fd в Epoll
  • принять клиента (использование клиента telnet) и добавить client_fd в epoll
  • отправить данные клиенту
  • после отсоединения кабеля, epoll_wait не получается любое событие, связанное с client_fd навсегда

Я хочу обнаружить ошибку в этой ситуации. Есть ли дополнительное решение? Нужно ли приложению применять метод сердечного ритма для самопроверки?

ответ

1

У вас есть два варианта здесь:

  • Реализовать сердцебиения на уровне приложений. Другими словами, вы пишете код, который обнаруживает незанятые соединения и периодически отправляет сообщение уровня приложения, чтобы существенно исследовать соединение и убедиться, что он все еще открыт.
  • Используется протокол 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 минуты.

0

Серверы Telnet используют протокол TCP keepalive; на самом деле это то, на что он действительно был изобретен.

Вы можете посылать нечеткую команду Telnet так часто.

Оба эти фактора в конечном итоге вызывают ECONNRESET.

+0

Что вы имеете в виду? Я не использовал telnet на стороне сервера. Я также создаю клиентское приложение для замены telnet, но получаю тот же результат. – thanhtv

Смежные вопросы