【Python3】IO多路复用示例代码

server.py

#! /usr/bin/evn python3
# coding:utf-8
import types
import socket
import selectors


sel = selectors.DefaultSelector()

def accept_wrapper(sock):
    conn, addr = sock.accept()
    print("accepted connection from", addr)

    conn.setblocking(False)
    event_mask = selectors.EVENT_READ | selectors.EVENT_WRITE
    data = types.SimpleNamespace(addr=addr, inb=b'', outb=b'')

    sel.register(conn, event_mask, data)

def service_connection(key, mask):
    sock, data = key.fileobj, key.data
    if mask & selectors.EVENT_READ:
        recv_data = sock.recv(1024)
        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)
            data.outb = data.outb[sent:]


addr = ('127.0.0.1', 8888)

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

sel.register(lsock, selectors.EVENT_READ, data=None)

while True:
    event = sel.select(timeout=None)
    # 遍历就绪的socket
    # key包含socket和data,mask是事件掩码
    for key, mask in event:
        if key.data is None:
            accept_wrapper(key.fileobj)
        else:
            service_connection(key, mask)

client.py

#! /usr/bin/env python3
# coding:utf-8

import selectors
import socket, types

sel = selectors.DefaultSelector()

for i in range(3):
    sock = socket.socket()
    sock.setblocking(False)
    sock.connect_ex(('127.0.0.1', 8888))

    event_mask = selectors.EVENT_READ | selectors.EVENT_WRITE

    data = types.SimpleNamespace(
        id=i,
        outb=b'i am a superman',
        recv_total=0,
        inb=b''
    )
    sel.register(sock, event_mask, data)

while True:
    try:
        events = sel.select(timeout=None)
    except OSError:
        print("OSError")
        break

    for key, mask in events:
        sock, data = key.fileobj, key.data
        if mask & selectors.EVENT_READ:
            recv_data = sock.recv(1024)
            if recv_data:
                print("received", repr(recv_data), "from connection", data.id)
                data.recv_total += len(recv_data)
            if not recv_data or data.recv_total == 15:
                print("closing connect", data.id)
                sel.unregister(sock)
                sock.close()

        if mask & selectors.EVENT_WRITE:
            if data.outb:
                print("sending", repr(data.outb), "to connection", data.id)
                data_len = sock.send(data.outb)
                data.outb = data.outb[data_len:]

你可能感兴趣的:(【Python3】IO多路复用示例代码)