Asyncio problem, looking for advice.

Benjamin Risher brisher777 at
Thu Nov 27 15:27:05 CET 2014

Hello all,

I'm working on a project to learn asyncio and network programming.  What I'm trying to do is forward a connection from myself to another machine.  Kind of like an asynchronous python implementation of fpipe.  

In a nutshell:

1 --> start a server listening on localhost
2 --> connect to server 
3 --> server connects to a listening service (ssh for instance)
4 --> server handles both connections to pass traffic back and forth through each

What I have now *kind of* works.  It sends data back and forth, but when I ssh to localhost -p 12345, i never get the password prompt.  It looks like one packet hangs out and doesn't get sent from what I saw in tcpdump.  

Any help would be greatly appreciated.  

Here's a link to the same code as below, just with syntax highlighting etc...

import asyncio
import logging

class MyServer:
    def __init__(self, loop):
        self.server = None
        self.loop = loop
        self.clients = dict()
        self.log = logging.getLogger(__name__)

    def _accept_client(self, client_reader, client_writer):
        """ Client initially drops in here """
        task = asyncio.Task(self._handle_client(client_reader, client_writer))
        self.clients[task] = (client_reader, client_writer)

        def client_done(task):
            self.clients[task][1].close()  # closes the StreamWriter that was part of the task
            del self.clients[task]"New connection.")

    def _handle_client(self, client_reader, client_writer):
        """ Try to connect to port 22 and broker between 2 connections.

        :param client_reader: StreamReader object
        :param client_writer: StreamWriter object
        reader, writer = yield from asyncio.async(asyncio.open_connection('localhost', 22))

        while True:
            client_data = yield from asyncio.async(self.read_data(client_reader))
            if client_data:
                yield from writer.drain()
            server_data = yield from asyncio.async(self.read_data(reader))
            if server_data:
                yield from client_writer.drain()

    def read_data(self, reader):
        data = None

        while True:
            print('top of while')
            data = yield from asyncio.Task(
            return data

    def start(self):
        """ start the server listening on 12345 """

        self.server = self.loop.run_until_complete(
                self._accept_client,                 # client_connected_callback
                'localhost',                         # host
                12345,                               # port
                loop=self.loop                       # loop

    def stop(self):
        if self.server:
            self.server = None

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    my_server = MyServer(loop)

More information about the Python-list mailing list