python IO多路复用 selectors

 

 

import selectors,socket,threading
selector=selectors.DefaultSelector()

def accept(socket:socket.socket):
    conn,client=socket.accept()
    print('accept new conn: {}'.format(conn))
    conn.setblocking(False)
    selector.register(conn,selectors.EVENT_READ,data=recv)

def recv(conn:socket.socket):
    data=conn.recv(1024)
    print(data)

#注册selector中监听的对象,事件和回调data(函数)
sock=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)

ip='127.0.0.1'
port=9999
sock.bind((ip,port))
sock.listen()
sock.setblocking(False)

e=threading.Event()
# 监控sock,可读时调用accept函数
key=selector.register(sock,selectors.EVENT_READ,accept)
print(key)


while not e.is_set():
    events=selector.select()  # select阻塞
    if events:  # events为二元列表
        print('event:',events)
    for key,mask in events:  # 对象key(fileobj,fd,events,data)
        print('key,mask:',key,mask)
        callback=key.data
        callback(key.fileobj)

 

import selectors,socket,threading
selector=selectors.DefaultSelector()

def accept(socket:socket.socket,mask):
    conn,client=socket.accept()
    print('accept new conn: {}'.format(conn))
    conn.setblocking(False)
    selector.register(conn,selectors.EVENT_READ | selectors.EVENT_WRITE,data=recv)

def recv(conn:socket.socket,mask):
    data=conn.recv(1024)
    print(data)


sock=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)

ip='127.0.0.1'
port=9999
sock.bind((ip,port))
sock.listen()
sock.setblocking(False)

#注册selector中监听的对象,事件和回调data(函数)
key=selector.register(sock,selectors.EVENT_READ,accept)
print(key)

e=threading.Event()

def work(event:threading.Event):
    while not event.is_set():
        events=selector.select()
        if events:
            print('events = {}'.format(events))
        for key,mask in events:
            print('key = {}'.format(key))
            print('mask = {}'.format(mask))
            callback=key.data
            callback(key.fileobj,mask)
try:
    threading.Thread(target=work,name='work thread',args=(e,)).start()
except OSError as e:
    print(e.errno,e.filename,e.filename2,e.strerror)

while not e.is_set():
    cmd=input('>>').strip()
    if cmd == 'quit':
        e.set()
        fobjs=[]
        print(selector.get_map().items())
        for fobj,key in selector.get_map().items():  # 注册的文件对象fd和key的映射
            print(fobj,key)
            print(key.fileobj)
            key.fileobj.close()
            fobjs.append(fobj)
        for v in fobjs:
            print('unregister {}'.format(v))
            selector.unregister(v)
    selector.close()

 

 

import threading,selectors,socket,datetime,sys

class Server:
    def __init__(self,ip='127.0.0.1',port=9999):
        self.addr=(ip,port)
        self.sock=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
        self.event=threading.Event()
        self.selector=selectors.DefaultSelector()
        self.clients={}

    def start(self):
        self.sock.bind(self.addr)
        self.sock.listen()
        self.sock.setblocking(False)
        self.selector.register(self.sock,selectors.EVENT_READ,data=self.__accept)
        threading.Thread(target=self.__run,name='run selector',daemon=True).start()

    def __run(self):
        while not self.event.is_set():
            events=self.selector.select(1)
            for key,mask in events:
                callback=key.data
                callback(key.fileobj,mask)

    def __accept(self,sock:socket.socket,mask):
        conn,client=sock.accept()
        self.clients[client]=conn
        conn.setblocking(False)
        self.selector.register(conn,selectors.EVENT_READ,self.__recv)

    def __recv(self,conn:socket.socket,mask):
        #ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
        #client主动断开时,server会抛异常
        try:
            data=conn.recv(1024).decode().strip()
        except ConnectionAbortedError as e:
            print(e.errno,e.filename,e.filename2,e.strerror)
            sys.exit(0)
        msg='{:%Y-%m-%d %H:%M:%S} {}:{} {}'.format(datetime.datetime.now(),*conn.getpeername(),data)
        print(msg)

        for key in self.selector.get_map().values():
            if key.data == self.__recv:  # 移除self.__accept
                key.fileobj.send(msg.encode())

    def stop(self):
        self.event.set()
        fd_list=[]
        for fd,key in self.selector.get_map().items():
            key.fileobj.close()
            fd_list.append(fd)

        for b in fd_list:
            self.selector.unregister(b)
        self.selector.close()

def main():
    vc=Server()
    vc.start()
    e=threading.Event()
    while not e.wait(2):
        cmd=input('>>').strip()
        if cmd == 'quit':
            vc.stop()
            e.wait(1)
            break

if __name__ == '__main__':
    main()

 

import threading,selectors,socket,datetime,sys,queue

class Conn:
    def __init__(self,conn:socket.socket,handle):
        self.conn=conn
        self.queue=queue.Queue()
        self.handle=handle

class Server:
    def __init__(self,ip='',port=9999):
        self.addr=(ip,port)
        self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.clients={}
        self.selector=selectors.DefaultSelector()
        self.event=threading.Event()

    def start(self):
        self.sock.bind(self.addr)
        self.sock.listen()
        self.sock.setblocking(False)
        self.selector.register(self.sock,selectors.EVENT_READ,self.__accept)
        threading.Thread(target=self.__run,name='run selector',daemon=True).start()

    def __run(self):
        while not self.event.is_set():
            events=self.selector.select(1)
            for key,mask in events:
                if callable(key.data):
                    callback=key.data
                else:
                    callback=key.data.handle
                callback(key.fileobj,mask)

    def __accept(self,sock:socket.socket,mask):
        conn,client=sock.accept()
        self.clients[client]=Conn(conn,self.__handle)
        conn.setblocking(False)
        self.selector.register(conn,selectors.EVENT_READ | selectors.EVENT_WRITE,self.clients[client])

    def __handle(self,conn:socket.socket,mask):
        if (mask & selectors.EVENT_READ) == selectors.EVENT_READ:
            data=conn.recv(1024).decode().strip()
            msg='{:%Y/%m/%d %H:%M:%S} {}:{} {}'.format(datetime.datetime.now(),*conn.getpeername(),data)
            print(msg)
            for c in self.clients.values():
                c.queue.put(msg.encode())

        if (mask & selectors.EVENT_WRITE) == selectors.EVENT_WRITE:
            remote=conn.getpeername()
            client=self.clients[remote]

            while not client.queue.empty():
                conn.send(client.queue.get())

    def stop(self):
        self.event.set()
        fd_list=[]
        for fd,key in self.selector.get_map():
            key.fileobj.close()
            fd_list.append(fd)

        for b in fd_list:
            self.selector.unregister(b)
        self.selector.close()

def main():
    e=threading.Event()
    s=Server()
    s.start()
    while not e.is_set():
        cmd=input('>>').strip()
        if cmd == 'quit':
            s.stop()
            e.wait(2)
            break

if __name__ == "__main__":
    main()

 

posted @ 2020-11-06 00:45  ascertain  阅读(146)  评论(0编辑  收藏  举报