【问题标题】:Why do paramiko produces false results while using with multi-threading?为什么 paramiko 在使用多线程时会产生错误的结果?
【发布时间】:2020-10-30 06:18:37
【问题描述】:

我正在尝试使用带有多线程的 paramiko SSH 到主机(数百个)。

这是我的多线程代码,

import paramiko
from concurrent.futures import ThreadPoolExecutor

# Initialising paramiko SSH Client
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# Fetching hosts
file = open("hosts.txt")
content = file.readlines()
hosts = [host.strip() for host in content]

def ssh(host):
    try:
        print("Connecting to", host)
        client.connect(host,
                       username="SOMEUSER",
                       password="SOMEPASS",
                       timeout=1,
                       banner_timeout=1,
                       auth_timeout=1)
        print("Connected to", host)
        # Need to check something here...
        client.close()
        print(f"Connection to {host} closed.")
        return True
    except:
        print("FAILED to connect", host)
        return False

with ThreadPoolExecutor(max_workers=4) as executor:
    results = list(executor.map(ssh, hosts))

for i, host in enumerate(hosts):
    print(host, "=>", results[i])

Q1:与没有任何多线程的代码相比,我得到了错误的结果。我的多线程在这里有什么问题,我怎样才能使它工作?

Q2:以某种方式引发了以下异常(多次),我不知道这个异常是如何没有被捕获的?

Exception: Error reading SSH protocol banner
Traceback (most recent call last):
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2211, in _check_banner
    buf = self.packetizer.readline(timeout)
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 380, in readline
    buf += self._read_timeout(timeout)
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 619, in _read_timeout
    raise EOFError()
EOFError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2039, in run
    self._check_banner()
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2216, in _check_banner
    "Error reading SSH protocol banner" + str(e)
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

【问题讨论】:

  • 首先增加你的超时时间。也许像这样的沉重负载会阻止数据及时到达。另外,您为什么要在几秒钟内创建数百个 SSH 连接?
  • 我需要定期检查主机中是否存在特定文件。我也尝试过 4 秒的超时,但没有帮助!此外,这些例外让我摸不着头脑
  • 为每个连接创建客户端怎么样?
  • @nagyl,真的成功了!非常感谢。
  • 不客气!:)

标签: python multithreading ssh paramiko


【解决方案1】:

在函数定义中移动 Paramiko SSH 客户端的初始化为我解决了问题!与没有多线程的代码相比,现在代码可以正常工作。

这是我解决问题后的代码

import paramiko
from concurrent.futures import ThreadPoolExecutor

file = open("hosts.txt")
content = file.readlines()
hosts = [host.strip() for host in content]

def ssh(host):
    try:
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        print("Connecting to", host)
        client.connect(host,
                       username="SOMEUSER",
                       password="SOMEPASS",
                       timeout=1,
                       banner_timeout=1,
                       auth_timeout=1)
        print("Connected to", host)
        # Need to check something here...
        client.close()
        print(f"Connection to {host} closed.")
        return True
    except:
        print("FAILED to connect", host)
        return False

with ThreadPoolExecutor(max_workers=4) as executor:
    output = list(executor.map(ssh, hosts))

for i, host in enumerate(hosts):
    print(host, "=>", output[i])

即使现在代码运行良好,但以下异常并没有被捕获!

Traceback (most recent call last):
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2211, in _check_banner
    buf = self.packetizer.readline(timeout)
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 380, in readline
    buf += self._read_timeout(timeout)
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/packet.py", line 607, in _read_timeout
    x = self.__socket.recv(128)
ConnectionResetError: [Errno 104] Connection reset by peer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2039, in run
    self._check_banner()
  File "/home/tesit/.local/lib/python3.6/site-packages/paramiko/transport.py", line 2216, in _check_banner
    "Error reading SSH protocol banner" + str(e)
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner[Errno 104] Connection reset by peer

【讨论】:

  • 也想抓住这个
猜你喜欢
  • 1970-01-01
  • 2016-01-24
  • 1970-01-01
  • 1970-01-01
  • 2017-06-05
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多