server.py

import socket
import selectors
import types

host, port = "127.0.0.1", 65432
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)   # register for conn, for later communication


def service_connection(key, mask):
    conn, data = key.fileobj, key.data      # conn socket actually
    
    if mask & selectors.EVENT_READ:
        recv_data = conn.recv(1024)  # Should be ready to read
        if recv_data:
            data.outb += recv_data
        else:
            print("closing connection to", data.addr)
            sel.unregister(conn)
            conn.close()
    if mask & selectors.EVENT_WRITE:
        if data.outb:
            print("echoing", repr(data.outb), "to", data.addr)
            sent = conn.send(data.outb)  # Should be ready to write
            data.outb = data.outb[sent:]


lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
lsock.bind((host, port))
lsock.listen()
print("listening on", (host, port))
lsock.setblocking(False)

# later listening operation committed to sel
# server was registered without data
sel.register(lsock, selectors.EVENT_READ, data=None)

try:
    while True:
        events = sel.select(timeout=None)   # when read operation is allowed
        for key, mask in events:
            if key.data is None:    # now we know it is server here, ready to accept connection
                accept_wrapper(key.fileobj)
            else:
                service_connection(key, mask)   # conn here, services should be offered
except KeyboardInterrupt:
    print("caught keyboard interrupt, exiting")
finally:
    sel.close()

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容