2015-09-07

Check if socket is broken in Python

Context
You set up a socket from client to server for communication. And you want to get informed when socket is broken.

Problem
If the socket is closed from server, client side receives no more data from socket. However, if server is shutdown in accident or network connection is broken, you may not get any hint.

Solution
Set socket option with TCP keep-alive as following:

_socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
try:
    _socket.recv(1024)
except socket.error as e:
    handle_socket_error(e)

When socket is broken, TCP keep-alive is failed. Then socket.error is raised while socket.recv(). By default keep-alive time is no less than two hours and this exception may be raised up to two hours. If you want more responsive on socket broken, need to reduce the keep-alive time.

For Linux:
_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec)
_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval_sec)
_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)

For OSX:
TCP_KEEPALIVE = 0x10
_socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPALIVE, interval_sec)

For Windows:
_socket.ioctl(socket.SIO_KEEPALIVE_VALS, (1, keepalive_time_msec, keepalive_interval_msec))

Note on Windows platform, the unit of time is millisecond.

Reference
[1] https://docs.python.org/2/library/socket.html
[2] http://stackoverflow.com/a/14855726/1249320
[3] https://msdn.microsoft.com/en-us/library/dd877220%28v=vs.85%29.aspx
Post a Comment