你不仅可以与调用write()funcation检测拔出以太网电缆。 这是因为tcp重传在没有你的意识的情况下由tcp堆栈执行。 这里有解决方案。
即使你已经设置keepalive选项到你的应用程序插座,你不能及时检测插座的死连接状态,在您的应用程序的情况下,在插座上不断书写。 这是因为内核tcp堆栈的tcp重传。 tcp_retries1和tcp_retries2是用于配置tcp重新传输超时的内核参数。 很难预测精确的重传超时时间,因为它是通过RTT机制计算的。 你可以在rfc793中看到这个计算。 (3.7。数据通信)
https://www.rfc-editor.org/rfc/rfc793.txt
每个平台具有用于TCP重发内核配置。
Linux : tcp_retries1, tcp_retries2 : (exist in /proc/sys/net/ipv4)
http://linux.die.net/man/7/tcp
HPUX : tcp_ip_notify_interval, tcp_ip_abort_interval
http://www.hpuxtips.es/?q=node/53
AIX : rto_low, rto_high, rto_length, rto_limit
http://www-903.ibm.com/kr/event/download/200804_324_swma/socket.pdf
您应该tcp_retries2(默认为15)如果你想及早发现死连接设置较低的值,但它的我已经没有精确的时间了说过。 另外,目前您不能仅为单个套接字设置这些值。这些是全局内核参数。 有一些试用申请单插槽(http://patchwork.ozlabs.org/patch/55236/)TCP重传套接字选项,但我不认为这是应用到内核主线。我无法在系统头文件中找到这些选项定义。
仅供参考,您可以监视通过像下面用“netstat --timers”你的keepalive套接字选项。 https://stackoverflow.com/questions/34914278
netstat -c --timer | grep "192.0.0.1:43245 192.0.68.1:49742"
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (1.92/0/0)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (0.71/0/0)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (9.46/0/1)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (8.30/0/1)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (7.14/0/1)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (5.98/0/1)
tcp 0 0 192.0.0.1:43245 192.0.68.1:49742 ESTABLISHED keepalive (4.82/0/1)
此外,当keepalive超时ocurrs,可满足您不同的返回事件取决于您使用的平台,所以你必须不返回事件决定只死连接状态。 例如,当Keepalive超时发生时,HP返回POLLERR事件,并且AIX仅返回POLLIN事件。 您当时会在recv()调用中遇到ETIMEDOUT错误。
在最近的内核版本(自2.6.37开始)之后,你可以使用TCP_USER_TIMEOUT选项将很好的工作。该选项可用于单个套接字。
最后,您可以使用带有MSG_PEEK标志的读取函数,它可以让您检查套接字是否正常。 (MSG_PEEK只是查看数据是否到达内核堆栈缓冲区,并且从不将数据复制到用户缓冲区中。) 因此,您可以使用此标志仅用于检查套接字是否正常,没有任何副作用。
问题是关于拔掉以太网电缆。 – EJP 2016-01-25 11:20:58