Benjamin Risher <brisher...@gmail.com> writes: > On Friday, November 28, 2014 6:12:20 AM UTC-6, Akira Li wrote: >> Benjamin Risher writes: >> >> > 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. >> >> Do you want to emulate `ssh -L 12345:localhost:22 <host>`? >> >> > Here's a link to the same code as below, just with syntax highlighting >> > etc... >> > http://pastebin.com/iLE4GZH3 >> >> There are several issue e.g., unnecessary async(), deprecated Task() >> calls but the main issue is that _handle_client() doesn't read >> concurrently from the server while client writes to it. >> >> You could use asyncio.wait() to run several tasks in parallel > >> [1] >> https://docs.python.org/3/library/asyncio-task.html#example-parallel-execution-of-tasks >> >> [2] http://pastebin.com/g08YaJyz >>
> Akira, > > First, thank you very much for your response. It helps tremendously. > I have a question or two though, if you don't mind. > > You said Task() is deprecated, but it's not listed as such in the > docs. Is it just that it's preferred to use other methods instead of > using Task() directly, or am I missing something? asyncio is a provisional API [3], it may change without notice (though it shouldn't without a reason). From asyncio docs [4]: Don’t directly create Task instances: use the async() function or the BaseEventLoop.create_task() method. The reason is probably to support Trollius (asyncio for Python 2) [5]. > Also, just so I can wrap my head around things, I was trying to mix > concurrent and procedural programming in the code I provided, correct? > Do you have any advice on how to avoid mixing types again in the > future? In short, the main issue was that your code executed some parts sequentially e.g., A then B: yield from A yield from B # this is not reached until A finishes that needed to be run concurrently: yield from asyncio.wait([A, B]) or in general, if you don't need to wait the results: asyncio.async(A) asyncio.async(B) # ... yield later, to pass the control to the event loop (Task._step/_fut_waiter dance ☯) Ask, if you have any specific questions about the code http://pastebin.com/g08YaJyz There is a bug at the end. info('done') should be outside the loop (improper indent). [3] https://www.python.org/dev/peps/pep-0411 [4] https://docs.python.org/3/library/asyncio-task.html#asyncio.Task [5] https://code.google.com/p/tulip/issues/detail?id=185 -- Akira -- https://mail.python.org/mailman/listinfo/python-list