import selectors import socket sel = selectors.DefaultSelector() total_blocks = 0 data = b"" def on_disconnect(conn): print("disconnected %s" % conn) sel.unregister(conn) conn.close() def accept(sock, mask): conn, addr = sock.accept() conn.setblocking(False) sel.register(conn, selectors.EVENT_READ, read) def write(conn, mask): global total_blocks, data # emulates a case where the first call to send() will always block sel.modify(conn, selectors.EVENT_WRITE, write) try: conn.send(data) except (ConnectionResetError, BrokenPipeError): on_disconnect(conn) except BlockingIOError as err: total_blocks += 1 sel.modify(conn, selectors.EVENT_WRITE, write) # print("err write %s %s" % (err, total_blocks)) data = b"" read(conn, mask) def read(conn, mask): global total_blocks, data # emulates a case where the first call to recv() will always block try: data += conn.recv(819200) # Should be ready if data: if b"\r\n" not in data: read(conn, mask) else: write(conn, mask) else: on_disconnect(conn) except (ConnectionResetError, BrokenPipeError): on_disconnect(conn) except BlockingIOError as err: total_blocks += 1 sel.modify(conn, selectors.EVENT_READ, read) # print("err read %s %s" % (err, total_blocks)) sock = socket.socket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('localhost', 1234)) sock.listen(100) sock.setblocking(False) sel.register(sock, selectors.EVENT_READ, accept) try: while True: events = sel.select() for key, mask in events: callback = key.data callback(key.fileobj, mask) finally: print("total_blocks would blocks = %s" % total_blocks)