【发布时间】:2019-06-07 13:47:26
【问题描述】:
我在 python 中编写了一个小代码,以使用 telnet 库在多个 Cisco 路由器上自动执行配置任务。在第一次迭代中一切正常,问题是我在函数 read_all() 的第二次迭代中超时。如果我从 telnetlib.Telnet() 函数中删除超时参数,我将永远停留在同一个迭代中。
from telnet import telnet
import xlrd
class handler:
excel_sheet=None
ipv4_devices=None
ipv6_devices=None
config=None
telnet=None
def __init__(self):
self.excel_sheet = xlrd.open_workbook("ipv4_devices.xlsx")
self.config=open("config.txt","r")
output_init = open("output.txt","w+")
output_init.write("")
output_init.close()
def execute(self):
row = None
column = None
self.ipv4_devices = self.excel_sheet.sheet_by_index(0)
for row in range(self.ipv4_devices.nrows-1):
self.telnet = telnet(self.ipv4_devices.cell_value(row+1,0),self.ipv4_devices.cell_value(row+1,1), self.ipv4_devices.cell_value(row+1,2), self.ipv4_devices.cell_value(row+1,3), self.config)
self.telnet.do_telnet()
self.telnet=None
self.config.close()
上面是我的 Handler.py 文件,它依次调用包含实际 telnet 代码的 telnet.py 文件。
import sys
import telnetlib
class telnet:
ipv4_address=None
port=0
username=None
passphrase=None
config=None
def __init__(self, ipv4_address=None, port=23, username=None, passphrase=None, config=None):
if (ipv4_address is not None) and (username is not None) and (passphrase is not None) and (config is not None) :
self.ipv4_address = ipv4_address
self.port = port
self.username = username
self.passphrase = passphrase
self.config = config
else:
exit()
def do_telnet(self):
output = open("output.txt","a")
remote= telnetlib.Telnet(self.ipv4_address,int(self.port))
remote.read_until("Username: ")
remote.write(self.username.encode('ascii')+"\n")
remote.read_until("Password: ")
remote.write(self.passphrase.encode('ascii')+"\n")
remote.write(self.config.read().encode('ascii')+"\n")
output.write(remote.read_all()+"\n"+" ------- "+"\n")
remote.close()
output.close()
当我超时时,以下是我得到的错误
Traceback (most recent call last):
File "Automate.py", line 5, in <module>
automate_it.execute()
File "/home/abdultayyeb/Desktop/Automation/handler.py", line 30, in execute
self.telnet.do_telnet()
File "/home/abdultayyeb/Desktop/Automation/telnet.py", line 31, in do_telnet
output.write(remote.read_all()+"\n"+" ------- "+"\n")
File "/usr/lib/python2.7/telnetlib.py", line 385, in read_all
self.fill_rawq()
File "/usr/lib/python2.7/telnetlib.py", line 576, in fill_rawq
buf = self.sock.recv(50)
socket.timeout: timed out
【问题讨论】:
-
如文档所述 read_all 将“以字节形式读取 EOF 之前的所有数据;阻塞直到连接关闭。”。换句话说:它不会读取服务器刚刚发送的所有内容,而是等待更多数据,直到服务器明确关闭连接 - 如果您只是通过 telnet 登录到某个地方并且似乎没有也发生在这里。因此,如果您期望得到特定的输出,您应该使用
read_until完全等待。 -
如果是这样,那为什么它在第一次迭代中没有被阻塞?为什么它在第二次迭代中被阻止,对于第二个 Cisco 路由器?
-
可能是因为路由器的行为不同,即一个路由器正在关闭连接而另一个没有。我不知道这些路由器应该如何表现。您可以尝试使用 telnet 手动连接,并检查路由器是否在发送数据后关闭连接。
标签: python sockets networking telnetlib