IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python IO 多路复用示例 -> 正文阅读

[Python知识库]Python IO 多路复用示例

1、简单 echo server

# echo server
import socket
import selectors

selec = selectors.DefaultSelector()  # 1、拿到selector
print(selec)

# 3、准备类文件对象,官方建议采用非阻塞IO
server = socket.socket()
server.bind(('127.0.0.1', 9999))
server.listen()
server.setblocking(False)


def accept(conn:socket.socket, mask:int):
    conn, raddr = server.accept()
    conn.setblocking(False)
    key = selec.register(conn, selectors.EVENT_READ, recv)
    print(key)
    print('conn', conn)
    print('raddr', raddr)


def recv(conn:socket.socket, mask:int):
    data = conn.recv(1024)
    print(data)
    msg = 'Your msg = {} from {}'.format(data.decode(), conn.getpeername()).encode()
    print(msg.decode())
    conn.send(msg)


# EVENT_READ = (1 << 0)
# EVENT_WRITE = (1 << 1)
# print(1 << 0, 1 << 1, 1 << 0 | 1 << 1)
# 1 2 3
# register(self, fileobj, events, data=None)
# data什么类型都可以写,函数当然也可以
# 2、注册关注的类文件对象和其它事件
# fileobj  fd  events data  构成  key
key = selec.register(server, selectors.EVENT_READ, accept)  # socket fileobject
print(key)
print(type(key))
print(key.__class__.mro())


# 当注册的文件对象们,这其中的至少一个对象关注的事情就绪了,就不阻塞了
# 获得了就绪的对象们,包括就绪的事件,还会返回data

while True:
    events = selec.select()  # epoll select  默认是阻塞的
    print(events)

    for key, mask in events:  # events => key, mask
        # 每一个event都是某一个被观察的就绪的对象
        print(type(key), type(mask))
        print(key.data)
        key.data(key.fileobj, mask)

server.close()
selec.close()
<selectors.SelectSelector object at 0x000001EA3F596F10>
SelectorKey(fileobj=<socket.socket fd=388, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=388, events=1, data=<function accept at 0x000001EA3F3BD280>)
<class 'selectors.SelectorKey'>
[<class 'selectors.SelectorKey'>, <class 'tuple'>, <class 'object'>]
[(SelectorKey(fileobj=<socket.socket fd=388, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=388, events=1, data=<function accept at 0x000001EA3F3BD280>), 1)]
<class 'selectors.SelectorKey'> <class 'int'>
<function accept at 0x000001EA3F3BD280>
SelectorKey(fileobj=<socket.socket fd=384, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63364)>, fd=384, events=1, data=<function recv at 0x000001EA3F73DAF0>)
conn <socket.socket fd=384, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63364)>
raddr ('127.0.0.1', 63364)
[(SelectorKey(fileobj=<socket.socket fd=388, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=388, events=1, data=<function accept at 0x000001EA3F3BD280>), 1)]
<class 'selectors.SelectorKey'> <class 'int'>
<function accept at 0x000001EA3F3BD280>
SelectorKey(fileobj=<socket.socket fd=360, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63367)>, fd=360, events=1, data=<function recv at 0x000001EA3F73DAF0>)
conn <socket.socket fd=360, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63367)>
raddr ('127.0.0.1', 63367)
[(SelectorKey(fileobj=<socket.socket fd=388, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=388, events=1, data=<function accept at 0x000001EA3F3BD280>), 1)]
<class 'selectors.SelectorKey'> <class 'int'>
<function accept at 0x000001EA3F3BD280>
SelectorKey(fileobj=<socket.socket fd=356, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63369)>, fd=356, events=1, data=<function recv at 0x000001EA3F73DAF0>)
conn <socket.socket fd=356, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63369)>
raddr ('127.0.0.1', 63369)
[(SelectorKey(fileobj=<socket.socket fd=384, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63364)>, fd=384, events=1, data=<function recv at 0x000001EA3F73DAF0>), 1)]
<class 'selectors.SelectorKey'> <class 'int'>
<function recv at 0x000001EA3F73DAF0>
b'123456789'
Your msg = 123456789 from ('127.0.0.1', 63364)
[(SelectorKey(fileobj=<socket.socket fd=360, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63367)>, fd=360, events=1, data=<function recv at 0x000001EA3F73DAF0>), 1)]
<class 'selectors.SelectorKey'> <class 'int'>
<function recv at 0x000001EA3F73DAF0>
b'123456789'
Your msg = 123456789 from ('127.0.0.1', 63367)
[(SelectorKey(fileobj=<socket.socket fd=360, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63367)>, fd=360, events=1, data=<function recv at 0x000001EA3F73DAF0>), 1)]
<class 'selectors.SelectorKey'> <class 'int'>
<function recv at 0x000001EA3F73DAF0>
b'123456789'
Your msg = 123456789 from ('127.0.0.1', 63367)

2、优化 echo server

import selectors
import socket
import logging

FORMAT = "%(asctime)s %(threadName)10s %(thread)8d %(message)s"
logging.basicConfig(level=logging.INFO, format=FORMAT)


# choose the best selector in this system
selector = selectors.DefaultSelector()

# create a fileobject
sock = socket.socket()  # TCP Server
sock.bind(('127.0.0.1', 9999))
sock.listen()
logging.info(sock)

sock.setblocking(False)  # non-blocking

# define call-back function, the read-event of sock
def accept(sock:socket.socket, mask:int):
    logging.info('start in accept function ~~~~~')
    conn, raddr = sock.accept()
    conn.setblocking(False)

    logging.info('New clinet socket [{}] is in accepting.'.format(conn))

    key = selector.register(conn, selectors.EVENT_READ, read)
    logging.info(key)
    logging.info('end in accept function ~~~~~')

# call-back function
def read(conn:socket.socket, mask:int):
    logging.info('start in read function ~~~~~')
    data = conn.recv(1024)
    msg = "Your msg = {} ~~~~~~~~~~~".format(data.decode())
    logging.info(msg)
    conn.send(msg.encode())
    logging.info('end in read function~~~~~')


key = selector.register(sock, selectors.EVENT_READ, accept)
logging.info(key)

while True:
    events = selector.select()
    print('events ===>', events)
    for key, mask in events:
        key.data(key.fileobj, mask)
2022-04-30 18:49:22,158 MainThread     2640 <socket.socket fd=372, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>
2022-04-30 18:49:22,159 MainThread     2640 SelectorKey(fileobj=<socket.socket fd=372, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=372, events=1, data=<function accept at 0x000002680D0878B0>)
events ===> [(SelectorKey(fileobj=<socket.socket fd=372, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=372, events=1, data=<function accept at 0x000002680D0878B0>), 1)]
2022-04-30 18:49:28,834 MainThread     2640 start in accept function ~~~~~
2022-04-30 18:49:28,834 MainThread     2640 New clinet socket [<socket.socket fd=400, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 60145)>] is in accepting.
2022-04-30 18:49:28,834 MainThread     2640 SelectorKey(fileobj=<socket.socket fd=400, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 60145)>, fd=400, events=1, data=<function read at 0x000002680D276C10>)
2022-04-30 18:49:28,834 MainThread     2640 end in accept function ~~~~~
events ===> [(SelectorKey(fileobj=<socket.socket fd=400, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 60145)>, fd=400, events=1, data=<function read at 0x000002680D276C10>), 1)]
2022-04-30 18:49:38,068 MainThread     2640 start in read function ~~~~~
2022-04-30 18:49:38,068 MainThread     2640 Your msg = 60145 ~~~~~~~~~~~
2022-04-30 18:49:38,068 MainThread     2640 end in read function~~~~~
2022-04-30 18:50:04,452 MainThread     2640 start in accept function ~~~~~
2022-04-30 18:50:04,452 MainThread     2640 New clinet socket [<socket.socket fd=404, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 60160)>] is in accepting.
2022-04-30 18:50:04,452 MainThread     2640 SelectorKey(fileobj=<socket.socket fd=404, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 60160)>, fd=404, events=1, data=<function read at 0x000002680D276C10>)
2022-04-30 18:50:04,452 MainThread     2640 end in accept function ~~~~~
events ===> [(SelectorKey(fileobj=<socket.socket fd=372, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=372, events=1, data=<function accept at 0x000002680D0878B0>), 1)]
2022-04-30 18:50:12,404 MainThread     2640 start in read function ~~~~~
2022-04-30 18:50:12,404 MainThread     2640 Your msg = 60160 ~~~~~~~~~~~
2022-04-30 18:50:12,404 MainThread     2640 end in read function~~~~~
events ===> [(SelectorKey(fileobj=<socket.socket fd=404, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 60160)>, fd=404, events=1, data=<function read at 0x000002680D276C10>), 1)]
2022-04-30 18:50:18,101 MainThread     2640 start in accept function ~~~~~
2022-04-30 18:50:18,102 MainThread     2640 New clinet socket [<socket.socket fd=364, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 60171)>] is in accepting.
2022-04-30 18:50:18,102 MainThread     2640 SelectorKey(fileobj=<socket.socket fd=364, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 60171)>, fd=364, events=1, data=<function read at 0x000002680D276C10>)
2022-04-30 18:50:18,102 MainThread     2640 end in accept function ~~~~~
events ===> [(SelectorKey(fileobj=<socket.socket fd=372, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=372, events=1, data=<function accept at 0x000002680D0878B0>), 1)]
events ===> [(SelectorKey(fileobj=<socket.socket fd=364, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 60171)>, fd=364, events=1, data=<function read at 0x000002680D276C10>), 1)]
2022-04-30 18:50:27,282 MainThread     2640 start in read function ~~~~~
2022-04-30 18:50:27,282 MainThread     2640 Your msg = 60171 ~~~~~~~~~~~
2022-04-30 18:50:27,282 MainThread     2640 end in read function~~~~~

3、群聊 server

# IO
# CHAT TCP SERVER
import selectors
import threading
import socket
import logging
import time

FORMAT = "%(asctime)s %(threadName)10s %(thread)8d %(message)s"
logging.basicConfig(level=logging.INFO, format=FORMAT)


class ChatServer:
    def __init__(self, ip='127.0.0.1', port=9999):
        self.sock = socket.socket()
        self.addr = ip, port
        self.event = threading.Event()
        self.selector = selectors.DefaultSelector()

    def start(self):
        self.sock.bind(self.addr)
        self.sock.listen()
        self.sock.setblocking(False)

        # 注册sock的被关注事件,返回SelectorKey对象
        # key记录了fileobj、fileobj的fd、events、data
        self.selector.register(self.sock, selectors.EVENT_READ, self.accept)
        # 事件监听循环
        threading.Thread(target=self.select, name='select', daemon=True).start()

    def select(self):
        # 开始循环
        while not self.event.is_set():
            # 监听注册的对象的事件,发生被关注事件则返回events
            events = self.selector.select()
            print('events ===>', events)  # [(key, mask)]
            # 表示那个关注的对象的某事件发生了
            for key, mask in events:
                # key.data => accept; key.fileobj => sock
                callback = key.data
                callback(key.fileobj, mask)

    # 回调函数,sock的读事件
    # 形参自定义
    def accept(self, sock:socket.socket, mask:int):
        conn, raddr = sock.accept()
        conn.setblocking(False)
        logging.info('new client socket {} is in accept.'.format(conn))
        key = self.selector.register(conn, selectors.EVENT_READ, self.recv)
        logging.info(key)

    # 回调函数
    def recv(self, conn:socket.socket, mask:int):
        data = conn.recv(1024).strip()

        if data == 'quit' or data == b'':
            self.selector.unregister(conn)
            conn.close()
            return

        msg = "Your msg = {} ~~~~~~".format(data.decode()).encode()
        logging.info(msg)

        for key in self.selector.get_map().values():
            print(list(self.selector.get_map()))
            print(self.recv)  # 当前绑定的
            print(key.data)  # 注册时注入的绑定的对象
            print(self.recv is key.data)
            print(self.recv == key.data)
            if key.data == self.recv:
                key.fileobj.send(msg)

    def stop(self):
        self.event.is_set()
        fobjs = []
        for fd, key in self.selector.get_map().items():
            fobjs.append(key.fileobj)
        for fobj in fobjs:
            self.selector.unregister(fobj)
            fobj.close()
        self.selector.close()


if __name__ == '__main__':
    cs = ChatServer()
    cs.start()
    while True:
        cmd = input('>>>>>>>').strip()
        if cmd == 'quit':
            logging.info('Quit.')
            cs.stop()
            break
        print(threading.enumerate())
>>>>>>>events ===> [(SelectorKey(fileobj=<socket.socket fd=344, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=344, events=1, data=<bound method ChatServer.accept of <__main__.ChatServer object at 0x000002E16B3AB0A0>>), 1)]
2022-04-30 22:53:41,564     select    34804 new client socket <socket.socket fd=412, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63182)> is in accept.
2022-04-30 22:53:41,564     select    34804 SelectorKey(fileobj=<socket.socket fd=412, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63182)>, fd=412, events=1, data=<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>)
events ===> [(SelectorKey(fileobj=<socket.socket fd=344, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=344, events=1, data=<bound method ChatServer.accept of <__main__.ChatServer object at 0x000002E16B3AB0A0>>), 1)]
2022-04-30 22:54:35,294     select    34804 new client socket <socket.socket fd=416, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63187)> is in accept.
2022-04-30 22:54:35,294     select    34804 SelectorKey(fileobj=<socket.socket fd=416, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63187)>, fd=416, events=1, data=<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>)
events ===> [(SelectorKey(fileobj=<socket.socket fd=344, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999)>, fd=344, events=1, data=<bound method ChatServer.accept of <__main__.ChatServer object at 0x000002E16B3AB0A0>>), 1)]
2022-04-30 22:54:44,573     select    34804 new client socket <socket.socket fd=420, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63188)> is in accept.
2022-04-30 22:54:44,573     select    34804 SelectorKey(fileobj=<socket.socket fd=420, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63188)>, fd=420, events=1, data=<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>)
2022-04-30 22:54:56,836     select    34804 b'Your msg = 63188 ~~~~~~'
events ===> [(SelectorKey(fileobj=<socket.socket fd=420, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63188)>, fd=420, events=1, data=<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>), 1)]
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.accept of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
False
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
True
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
True
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
True
2022-04-30 22:55:16,936     select    34804 b'Your msg = 63187 ~~~~~~'
events ===> [(SelectorKey(fileobj=<socket.socket fd=416, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63187)>, fd=416, events=1, data=<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>), 1)]
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.accept of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
False
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
True
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
True
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
True
events ===> [(SelectorKey(fileobj=<socket.socket fd=412, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63182)>, fd=412, events=1, data=<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>), 1)]
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.accept of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
False
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
True
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
True
[344, 412, 416, 420]
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>
False
True
2022-04-30 22:55:23,834     select    34804 b'Your msg = 63182 ~~~~~~'
events ===> [(SelectorKey(fileobj=<socket.socket fd=412, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63182)>, fd=412, events=1, data=<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>), 1)]
events ===> [(SelectorKey(fileobj=<socket.socket fd=416, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63187)>, fd=416, events=1, data=<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>), 1)]
events ===> [(SelectorKey(fileobj=<socket.socket fd=420, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 63188)>, fd=420, events=1, data=<bound method ChatServer.recv of <__main__.ChatServer object at 0x000002E16B3AB0A0>>), 1)]

[<_MainThread(MainThread, started 11656)>, <Thread(select, started daemon 34804)>]
>>>>>>>quit
events ===>2022-04-30 22:55:41,392 MainThread    11656 Quit.

Process finished with exit code 0
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:14:27  更:2022-05-05 11:18:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 16:18:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码