我想提几点...
1) 根据this document,在Linux中使用keepalive需要以下内容:
Linux has built-in support for keepalive. You need to enable TCP/IP
networking in order to use it. You also need procfs support and sysctl
support to be able to configure the kernel parameters at runtime.
The procedures involving keepalive use three user-driven variables:
tcp_keepalive_time
> the interval between the last data packet sent (simple ACKs are not
considered data) and the first keepalive probe; after the connection
is marked to need keepalive, this counter is not used any further
tcp_keepalive_intvl
> the interval between subsequential keepalive probes, regardless of
what the connection has exchanged in the meantime
tcp_keepalive_probes
> the number of unacknowledged probes to send before considering the
connection dead and notifying the application layer
Remember that keepalive support, even if configured in the kernel, is
not the default behavior in Linux. Programs must request keepalive
control for their sockets using the setsockopt interface. There are
relatively few programs implementing keepalive, but you can easily add
keepalive support for most of them following the instructions
explained later in this document.
尝试查看当前系统中这些变量的当前值,以确保它们是正确的或有意义的。粗体突出是我的,看起来你正在这样做。
我假设这些变量的值是以毫秒为单位的,但不确定,请再次确认。
tcp_keepalive_time
我期望一个值,意思大约是“在最后一个数据包发送后尽快发送第一个探测包”。
tcp_keepalive_intvl
我猜这个变量的值应该比TCP默认关闭连接所需的时间少。
tcp_keepalive_probes
这可能是决定你的应用程序成败的“魔法值”;如果未确认探测的数量过高,可能是导致epoll_wait()
永远不会退出的原因。
该文档讨论了Linux内核版本(2.4.x、2.6.x)中TCP keepalive的实现,以及如何在C语言中编写启用TCP keepalive的应用程序。
http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/
2) 确保在 epoll_wait()
的超时参数中不指定 -1,因为这会导致 epoll_wait()
无限期地阻塞。
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
timeout参数指定了epoll_wait()函数将会阻塞的最小毫秒数。(这个时间间隔将会被舍入到系统时钟粒度,并且内核调度延迟意味着阻塞时间可能会超过一小段时间。)指定timeout为-1会导致epoll_wait()无限期地阻塞,而指定timeout等于零会导致epoll_wait()立即返回,即使没有事件可用。来自手册页面
http://linux.die.net/man/2/epoll_wait。