如何使用 python 脚本更改 tcp keepalive 计时器?

Posted

技术标签:

【中文标题】如何使用 python 脚本更改 tcp keepalive 计时器?【英文标题】:How to change tcp keepalive timer using python script? 【发布时间】:2012-08-28 04:58:01 【问题描述】:

在我的 python 脚本中,我使用这个命令激活了 TCP Keepalive:

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

如果 5 分钟内没有传输(*),我的目标是关闭套接字连接。我在 Windows 上工作,我的 python 脚本只接收而不向客户端程序传输任何数据。

我所知道的是,默认情况下,如果 2 小时内没有传输,那么只有我可以使用 try 和 except 关闭连接。我知道,对于 Windows,我可以通过转到注册表来手动减少等待时间。但是有没有一种方法可以让我从我的脚本中修改它?

(*) 这里的“不传输”是指“有东西悄悄地吃掉网络上的数据包”,而不是“我不想发送任何东西”。

【问题讨论】:

澄清了“不传输”的含义。 【参考方案1】:

您可以使用 setsockopt() 在已打开的套接字上设置 TCP keepalive 计时器。

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)

对于 Windows refer to msdn 上的等效选项。 查看Python source,您似乎需要设置SO_KEEPALIVEsock.setsockopt,类似于在Unix 中,并且[可选?] 设置SIO_KEEPALIVE_VALSsock.ioctl

【讨论】:

请注意,此处使用的 TCP_* 常量特定于 Linux。例如,它们在 OS/X 上不可用 osx man tcp 包含一个选项 TCP_KEEPALIVE,它接受探测之间的秒数,相当于 linux 中的 TCP_KEEPINTVL。选项未在 Python 2.7 或 3.3 中导出,但我认为可以使用正确的整数值 0x10 作为键。 @DimaTisnek TCP_KEEPINTVL 看起来是等价的,但你是如何得到这个值的 0x10 达尔文tcp.h: github.com/apple/darwin-xnu/blob/… 关于 Solaris 的任何想法 - '_socketobject' 对象没有属性 'IPPROTO_TCP',也没有 SOL_SOCKET【参考方案2】:

对于 windows,在 python 中:

这将启用套接字保持活动状态,保持活动时间为 10 秒,保持活动时间间隔为 3 秒。

sock.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 10000, 3000))

【讨论】:

以上是关于如何使用 python 脚本更改 tcp keepalive 计时器?的主要内容,如果未能解决你的问题,请参考以下文章

KeepAliveHttp--Keep-Alive及Tcp--Keepalive

http的keep-alive和tcp的keepalive区别

健壮的连续 TCP 连接(python 套接字)

Http长连接和Keep-Alive以及Tcp的Keepalive

Python socket-module:如何更改客户端的本地端口?

TCP keep-alive翻译