Alex
Alex

Reputation: 44385

How to use telnetlib3 to write and read to/from a telnet connection using python?

I am trying to use telnetlib3 with python 3.8.10 to open a connection, write data to it and try to read the reply. This is the code I am using:

reader,writer = asyncio.run(telnetlib3.open_connection(host, port))
writer.write("$SYS,INFO")
reply = asyncio.run(reader.read())

However, I get the following error for which I have no idea what it means, and for which I do not really find anything useful with google:

RuntimeError: Task <Task pending name='Task-3' coro=<TelnetReaderUnicode.read() running at /home/alex/.local/lib/python3.8/site-packages/telnetlib3/stream_reader.py:206> cb=[_run_until_complete_cb() at /usr/lib/python3.8/asyncio/base_events.py:184]> got Future <Future pending> attached to a different loop

Can this be fixed? How to use telnetlib3 properly?

Upvotes: 0

Views: 3207

Answers (1)

larsks
larsks

Reputation: 312400

Each call to asyncio.run() is spawning a different event loop. You need to put all your code into the same loop:

import asyncio
import telnetlib3

async def main():
    reader, writer = await telnetlib3.open_connection('localhost', 2300)
    writer.write("$SYS,INFO")
    reply = await reader.read()
    print('reply:', reply)


asyncio.run(main())

Note that read() is a blocking method; if the connection isn't closed after the reply is sent, it may end up blocking indefinitely. You can read character-by-character instead, if there is a specific delimiter that marks the end of the reply. E.g., if we expect the reply to be terminated with an EOL character:

import asyncio
import telnetlib3

async def main():
    reader, writer = await telnetlib3.open_connection('localhost', 2300)
    writer.write("$SYS,INFO")

    reply = []
    while True:
        c = await reader.read(1)
        if not c:
            break

        if c in ['\r', '\n']:
            break

        reply.append(c)

    print('reply:', ''.join(reply))


asyncio.run(main())

As for "how do I create a class out of it?", I'm not sure how to answer that. The example above could be written like:

import asyncio
import telnetlib3

class Communicator:
    def __init__(self, host, port):
        self.host = host
        self.port = port

    async def connect(self):
        self.reader, self.writer = await telnetlib3.open_connection(self.host, self.port)

    async def get_info(self):
        self.writer.write("$SYS,INFO")

        reply = []
        while True:
            c = await self.reader.read(1)
            if not c:
                break

            if c in ['\r', '\n']:
                break

            reply.append(c)

        return ''.join(reply)

async def main():
    conn = Communicator('localhost', 2300)
    await conn.connect()
    print('info:', await conn.get_info())


asyncio.run(main())

That's not necessarily a great example, but it works. There are additional examples in the telnetlib3 documentation that may also be of interest.

Upvotes: 2

Related Questions