我已经测试epoll
,以防网络电缆拔掉:
server_fd
添加到epoll telnet
)并将client_fd
添加到epoll epoll_wait
没有任何与永久client_fd
相关的事件我想在这种情况下检测错误。还有其他解决方案吗?应用程序是否需要实现心跳方法来自我检测?
答案 0 :(得分:1)
这里有两个选项:
要启用和配置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
。