问题描述
我很难让asyncio与telnetlib配合使用来询问一些硬件。
我想我显然不了解asyncio的工作方式,我完全迷失了所有这些。真的不清楚。
我的基本版本(同步)运行良好,但查询设备的完整清单实际上需要6个小时,而且大部分设备都无法响应,因为它们无法到达。
由于Asyncio使我们能够并行化连接,而不必等待每次超时触发,因此我想将代码转换为适当的异步代码而没有成功。
这是我尝试过的:
import telnetlib
import time
import datetime
import asyncio
from env.fonctions import *
from env.variables import *
first_cmds = ['term length 0',\
'show run',\
'exit']
#create lists to iterate through
hosts = ['router-1','router-2','router-3','router-4','router-5']
async def main(hosts,user_rw_hw,password_rw_hw,first_cmds):
class ContinueI(Exception):
pass
continue_i = ContinueI()
for host in hosts:
print(f'{host} | Trying to connect...')
try:
tn = await async_establish_telnet_connexion(user_rw_hw,host,23,0.5,True)
except:
continue
print(f'{host} | Checking if equipment is not Nexus')
tn.write('show version'.encode('ascii') + b"\n")
sh_ver = await async_read_telnet_output(tn)
if 'Nexus' in sh_ver or 'NX-OS' in sh_ver or 'nexus' in sh_ver:
print(f'{host} | Equipment is Nexus,closing connection...')
tn.write('exit'.encode('ascii') + b"\n")
continue
tn.write(''.encode('ascii') + b"\n")
try:
for cmd in first_cmds:
tn.write(cmd.encode('ascii') + b"\n")
if not 'exit' in cmd:
response = await async_read_telnet_output(tn)
if '\r\n% Invalid' in response:
print(f'{host} | Commande "{cmd}" pas reconnue')
raise continue_i
else:
print(f'{host} | Commands are accepted')
except ContinueI:
tn.write(b"exit\n")
tn.write(b"exit\n")
print(f'{host} | logout for command not recognized')
continue
if __name__ == "__main__":
try:
loop = asyncio.get_event_loop()
loop.set_debug(1)
loop.run_until_complete(main(hosts,first_cmds))
except Exception as e:
pass
finally:
loop.close()
和功能:
async def async_read_telnet_output(tn,timeout=2,timestep=0.1):
timer = 0
data = b''
while timer <= timeout:
new_datas = tn.read_very_eager()
if len(new_datas) != 0:
timer = 0
data += new_datas
await asyncio.wait(timestep)
timer += timestep
return data.decode('utf-8')
async def async_establish_telnet_connexion(user_rw_hw,port=23,timeout=1,debug=False):
try:
tn = telnetlib.Telnet(host,port) # Here I don't kNow how to make it awaitable,if I put await before the IDE said that this method is not an awaitable,btw even if I put an awaitable like "asyncio.sleep" the behavior is still the same so it's not the only point bad
except:
if debug == True:
print(f"{host} | Telnet not responding.")
raise Exception
if debug == True:
print(f"{host} | Telnet is responding.")
response = loop.create_task(async_read_telnet_output(tn,15))
if not 'Username:' in response and not 'login' in response:
if debug == True:
print(f"{host} | Don't see Username asked by equipment.")
raise Exception
else:
tn.write(user_rw_hw.encode('ascii') + b"\n")
if debug == True:
print(f"{host} | Username entered.")
try:
await tn.read_until(b"Password: ",timeout)
except:
if debug == True:
print(f"{host} | Don't see Password asked by equipment.")
raise Exception
finally:
tn.write(password_rw_hw.encode('ascii') + b"\n")
response = await async_read_telnet_output(tn,10)
if '% Authentication Failed' in response or 'Rejected' in response:
if debug == True:
print(f"{host} | Connection Failed bad credentials.")
raise Exception
if debug == True:
print(f"{host} | Connection succeed waiting for commands.")
return tn
如果有人知道我要失败的地方,我将不胜感激,因为我已经呆了一个星期了……读一些书和youtube tutos,但无济于事。
先谢谢您!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)