【问题标题】:Paramiko not closing SSH connections - MultithreadParamiko 没有关闭 SSH 连接 - 多线程
【发布时间】:2016-06-06 22:42:38
【问题描述】:

我正在使用paramiko 发起ssh 连接。似乎在运行我的脚本时,一旦建立连接,它们就不会关闭。相反,直到TIME_WAIT 用完,连接才会终止。我知道TIME_WAIT 表示等待足够的时间来确保远程 TCP 收到其连接终止请求的确认。

这是我的代码:

#!/usr/local/bin/python2.7
import sys, os, string, threading
import paramiko

paramiko.util.log_to_file("paramiko.log")

cmd = "hostname"

outlock = threading.Lock()

def workon(host):

    ssh = paramiko.SSHClient()
    key = paramiko.RSAKey.from_private_key_file("./key")
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(host, username='user', pkey=key)
    stdin, stdout, stderr = ssh.exec_command(cmd)

    with outlock:
        result = stdout.readlines()
        print "{0}".format(hostname[0])
        ssh.close()

def main():

    with open('./ip_list') as ip:
        hosts = ip.read().splitlines()

    threads = []
    for h in hosts:
        t = threading.Thread(target=workon, args=(h,))
        t.start()
        threads.append(t)
    for t in threads:
        t.join()

if __name__ == "__main__":
    main()

也许这是正常行为,但我想确定一下。在数百个 IP 地址上运行此脚本时,脚本完成后,服务器上的大量套接字会在几分钟内保持打开状态。

让我感到困惑的是,套接字在连接时得到ESTABLISHED,然后转到TIME_WAIT——即使我没有调用close() 方法。这是预期的行为吗?我什至不应该打扰调用close() 方法吗?有没有“更好”的方法来做到这一点?

【问题讨论】:

    标签: python multithreading python-2.7 ssh paramiko


    【解决方案1】:

    TIME_WAIT 是您(作为客户端)在干净地关闭连接时应该进入的状态。因此,您应该等待以确保对方“看到”您的FIN/ACK。如果您在没有调用close() 的情况下突然退出,清理时也会发生同样的情况。

    直接使用套接字,您可以关闭连接并“立即”释放资源(如果这是您想要的),但根据documentation,不建议这样做。实际上发生的情况是在套接字上调用close() 并没有真正关闭套接字,而是等待GC 清理它。结果,RST/ACK 数据包被发送到另一端。因此它将继续使用资源,直到被 GC 关闭并且连接不会正确关闭。

    【讨论】: