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