我很难尝试让asyncio与telnetlib一起使用来询问一些硬件。
我想我显然不理解asyncio的工作方式,我完全迷失在这一切中。这真的很不清楚。
由于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 ,password_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, user_rw_hw ,password_rw_hw, 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, password_rw_hw, host, 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,但对我毫无帮助..
提前谢谢你!
发布于 2021-11-29 21:58:17
对于那些降落在这里的人。我找到了https://pypi.org/project/asynctelnet/
快速示例:
客户端:
import anyio, asynctelnet
async def shell(tcp):
async with asynctelnet.TelnetClient(tcp, client=True) as stream:
while True:
# read stream until '?' mark is found
outp = await stream.receive(1024)
if not outp:
# End of File
break
elif '?' in outp:
# reply all questions with 'y'.
await stream.send('y')
# display all server output
print(outp, flush=True)
# EOF
print()
async def main():
async with await connect_tcp('localhost', 56023) as client:
await shell(client)
anyio.run(main)服务器:
import anyio, asynctelnet
async def shell(tcp):
async with asynctelnet.TelnetServer(tcp) as stream:
# this will fail if no charset has been negotiated
await stream.send('\r\nWould you like to play a game? ')
inp = await reader.receive(1)
if inp:
await stream.echo(inp)
await stream.send('\r\nThey say the only way to win '
'is to not play at all.\r\n')
async def main():
listener = await anyio.create_tcp_listener(local_port=56023)
await listener.serve(shell)
anyio.run(main)尽管如此,这个库还是有一些bug。因此,当前的状态是“如果您想使用它,请准备编写一些bug解决方案”。
https://stackoverflow.com/questions/64809282
复制相似问题