使用epoll检测网络电缆未插入错误

时间:2015-07-09 03:01:06

标签: linux network-programming epoll

我已经测试epoll,以防网络电缆拔掉:

  • 服务器打开端口3000
  • 创建epoll并将server_fd添加到epoll
  • 接受客户端(客户端使用telnet)并将client_fd添加到epoll
  • 将数据发送到客户端
  • 拔掉电缆后,epoll_wait没有任何与永久client_fd相关的事件

我想在这种情况下检测错误。还有其他解决方案吗?应用程序是否需要实现心跳方法来自我检测?

2 个答案:

答案 0 :(得分:1)

这里有两个选项:

  • 实施应用层心跳。换句话说,您编写的代码可以检测空闲连接,并定期发送应用程序层消息,以便主要探测连接并确保它仍处于打开状态
  • 您使用TCP keepalive。这基本上将实现和处理心跳消息的工作转移到TCP层。在您的情况下,这似乎是一个不错的选择。

要启用和配置TCP keepalive,您需要使用client_fd更改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分钟。

答案 1 :(得分:0)

Telnet服务器使用TCP keepalive;确实这就是它真正发明的东西。

您可以经常发送一个无用的Telnet命令。

这两者最终都会导致ECONNRESET