Hi,
I have posted the same question to python-tutor list *, but I'm trying
my luck here as advised.
I'm trying to get more familiar with asyncio library. Using python
3.4, I wrote simple echo server (see attachement for the code). I know
that instead of using bare bone send/recv I could use some of the
helper functions, but I want to start with the basics.
Using attached code, I can connect from multiple sources, but echo
won't work for all clients. Also, please look at the `sendall` mehtod
- I have to manually remove write callback, otherwise it will be
called all the time. Any tips on solving this problem?
* https://mail.python.org/pipermail/tutor/2014-March/100679.html
import asyncio
import socket
import time
loop = asyncio.get_event_loop()
class Client:
def __init__(self, conn):
self.conn = conn
self.conn.setblocking(False)
def recv(self, size):
"wrap `recv` method with future"
future = asyncio.Future()
def _recv():
try:
future.set_result(self.conn.recv(size))
except Exception as exc:
future.set_exception(exc)
loop.add_reader(self.conn, _recv)
return future
def sendall(self, data):
"wrap `sendall` method with future"
future = asyncio.Future()
def _sendall():
try:
# XXX manually remove, because otherwise it will be called
# forever
loop.remove_writer(self.conn)
future.set_result(self.conn.sendall(data))
except Exception as exc:
future.set_exception(exc)
loop.add_writer(self.conn, _sendall)
return future
def close(self):
self.conn.close()
def accept(sock):
future = asyncio.Future()
def _accept_client():
conn, addr = sock.accept()
future.set_result((Client(conn), addr))
loop.add_reader(sock, _accept_client)
return future
def handle_client(conn, addr):
print("Client connected: {}".format(addr))
while True:
data = yield from conn.recv(1024)
if data.strip() == b'quit':
conn.close()
print("Client disconnected: {}".format(addr))
return
yield from conn.sendall(data)
@asyncio.coroutine
def test():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setblocking(False)
sock.bind(('localhost', 12345))
sock.listen(1)
while True:
conn, addr = yield from accept(sock)
asyncio.Task(handle_client(conn, addr))
def main():
loop.run_until_complete(test())
loop.close()
if __name__ == "__main__":
main()
--
https://mail.python.org/mailman/listinfo/python-list