12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- #!/usr/bin/env python3
- import sys
- import socket
- import selectors
- import types
- sel = selectors.DefaultSelector()
- def accept_wrapper(sock):
- conn, addr = sock.accept() # Should be ready to read
- print("accepted connection from", addr)
- conn.setblocking(False)
- data = types.SimpleNamespace(addr=addr, inb=b"", outb=b"")
- events = selectors.EVENT_READ | selectors.EVENT_WRITE
- sel.register(conn, events, data=data)
- def service_connection(key, mask):
- sock = key.fileobj
- data = key.data
- if mask & selectors.EVENT_READ:
- recv_data = sock.recv(1024) # Should be ready to read
- if recv_data:
- data.outb += recv_data
- else:
- print("Closing connection to", data.addr)
- sel.unregister(sock)
- sock.close()
- if mask & selectors.EVENT_WRITE:
- if data.outb:
- print("Echoing", repr(data.outb), "to", data.addr)
- sent = sock.send(data.outb) # Should be ready to write
- data.outb = data.outb[sent:]
- if len(sys.argv) < 3:
- print("Usage:", sys.argv[0], "<host> <port>")
- sys.exit(1)
- host, port = sys.argv[1], int(sys.argv[2])
- lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- lsock.bind((host, port))
- lsock.listen()
- print("Listening on", (host, port))
- lsock.setblocking(False)
- sel.register(lsock, selectors.EVENT_READ, data=None)
- try:
- while True:
- events = sel.select(timeout=None)
- for key, mask in events:
- if key.data is None:
- accept_wrapper(key.fileobj)
- else:
- service_connection(key, mask)
- except KeyboardInterrupt:
- print("caught keyboard interrupt, exiting")
- finally:
- sel.close()
|