How to change tcp keepalive timer using python script?

John picture John · Sep 3, 2012 · Viewed 35.9k times · Source

In my python script, I have activate TCP Keepalive using this command:

x = s.setsockopt( socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)

My goal is for socket connection to get closed, if there is no transmission(*) for 5 minutes. I am working on Windows and my python script is only receiving and not transmitting any data to client program.

What I know is, by default, if no transmission will be there for 2 hours, then only I can close the connection using try and except. I know, for windows, I can manually reduce this waiting time by going to registry. But is there is a way by which, I can modify it from my script?

(*) here "no transmission" means "something quietly eats packets on the network" rather than "I'm not trying to send anything."

Answer

Will Pierce picture Will Pierce · Feb 13, 2013

You can set the TCP keepalive timers on an already-open socket using setsockopt().

import socket

def set_keepalive_linux(sock, after_idle_sec=1, interval_sec=3, max_fails=5):
    """Set TCP keepalive on an open socket.

    It activates after 1 second (after_idle_sec) of idleness,
    then sends a keepalive ping once every 3 seconds (interval_sec),
    and closes the connection after 5 failed ping (max_fails), or 15 seconds
    """
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec)
    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval_sec)
    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)

def set_keepalive_osx(sock, after_idle_sec=1, interval_sec=3, max_fails=5):
    """Set TCP keepalive on an open socket.

    sends a keepalive ping once every 3 seconds (interval_sec)
    """
    # scraped from /usr/include, not exported by python's socket module
    TCP_KEEPALIVE = 0x10
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
    sock.setsockopt(socket.IPPROTO_TCP, TCP_KEEPALIVE, interval_sec)

For equivalent options on windows refer to msdn. Looking through the Python source, it seems you need to set SO_KEEPALIVE with sock.setsockopt similar to in Unix, and [optionally?] set SIO_KEEPALIVE_VALS with sock.ioctl.