You cannot detect a disconnected network cable with only the write () call function. This is because of the tcp retransmission performed by the tcp stack without your consciousness. Here are the solutions.
Even if you already set the keepalive parameter in your application socket, you will not be able to determine the status of a dead socket connection in a timely manner if your application continues to write to the socket. This is due to the retransmission of tcp in the tcp kernel stack. tcp_retries1 and tcp_retries2 are the kernel parameters for setting the tcp retransmission timeout. It is difficult to predict the exact timeout of the retransmission because it is calculated by the RTT mechanism. You can see this calculation in rfc793. (3.7. Data Transfer)
https://www.rfc-editor.org/rfc/rfc793.txt
All platforms have kernel configurations for retransmission of 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
You must set a lower value for tcp_retries2 (default is 15) if you want early detection of a dead connection, but this is not an exact time, as I said. In addition, you cannot currently set these values ββfor only one socket. These are global kernel parameters. There have been several attempts to apply the tcp retransmission socket option to a single socket ( http://patchwork.ozlabs.org/patch/55236/ ), but I do not think that it was applied in the core core. I cannot find such a definition of parameters in system header files.
For reference, you can track your keepalive socket option through 'netstat -timers', as shown below. 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)
In addition, when keepalive timeout ocurrs, you may encounter different return events depending on the platforms you are using, so you should not determine the dead state of the connection only with return events. For example, HP returns the POLLERR event, and AIX returns the POLLIN event when the keepalive timeout occurs. At this time, you will encounter the ETIMEDOUT error in the recv () call.
In the latest kernel version (starting from version 2.6.37) you can use the TCP_USER_TIMEOUT parameter, which will work well. This parameter can be used for a single socket.
Finally, you can use the read function with the MSG_PEEK flag, which allows you to check that the socket is in order. (MSG_PEEK just looks if the data goes to the kernel stack buffer and never copies the data to the user buffer). Thus, you can use this flag only to check the socket, without any side effects.