首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试使asyncio与telnetlib一起工作

尝试使asyncio与telnetlib一起工作
EN

Stack Overflow用户
提问于 2020-11-13 02:01:56
回答 1查看 250关注 0票数 0

我很难尝试让asyncio与telnetlib一起使用来询问一些硬件。

我想我显然不理解asyncio的工作方式,我完全迷失在这一切中。这真的很不清楚。

由于Asyncio使我们能够并行化连接,而无需等待每次超时触发,因此我希望将我的代码转换为适当的异步代码,但不会成功。

这是我尝试过的:

代码语言:javascript
复制
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()

和函数:

代码语言:javascript
复制
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,但对我毫无帮助..

提前谢谢你!

EN

回答 1

Stack Overflow用户

发布于 2021-11-29 21:58:17

对于那些降落在这里的人。我找到了https://pypi.org/project/asynctelnet/

快速示例:

客户端:

代码语言:javascript
复制
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)

服务器:

代码语言:javascript
复制
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解决方案”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64809282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档