select

 1import socket
 2import select
 3import gc
 4
 5HOST = "0.0.0.0"
 6PORT = 60000
 7BACKLOG = 5
 8
 9srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
10srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
11srv.bind((HOST, PORT))
12srv.listen(BACKLOG)
13srv.setblocking(False)
14
15poller = select.poll()
16poller.register(srv, select.POLLIN)
17
18clients = {}
19
20print(f"echo server on {HOST}:{PORT}")
21
22while True:
23    # wait for 100ms
24    for sock, event in poller.poll(100):
25        if sock is srv:
26            conn, addr = srv.accept()
27            conn.setblocking(False)
28            poller.register(conn, select.POLLIN)
29            clients[conn] = addr
30            print(f"client connected:", addr)
31        else:
32            if event & select.POLLIN:
33                data = sock.recv(1024)
34                if data:
35                    print("recv:", data)
36                    sock.send(data)
37                else:
38                    # peer closed
39                    print("client disconnected:", clients[sock])
40                    poller.unregister(sock)
41                    sock.close()
42                    del clients[sock]
43            elif event & select.POLLERR:
44                print("error on client:", clients[sock])
45                poller.unregister(sock)
46                sock.close()
47                del clients[sock]
48    gc.collect()