非阻塞套接字编程, IO多路复用(epoll)

非阻塞套接字编程:

server端

import socket


server = socket.socket()
server.setblocking(False)
server.bind(('', 8884))
server.listen(5)

clients = []

while True:
    try:
        conn, addr = server.accept()
        conn.setblocking(False)
    except BlockingIOError:
        pass
    else:
        print(f'用户{addr[0]},建立了连接。')
        clients.append(conn)
   all_conn_data = [conn for conn inn clients] # 迭代新列表,防止数据紊乱(避免在迭代对象的时候修改对象,造成数据紊乱)
for conn in all_conn_data: try: res = conn.recv(1024) if res: print(res) else: conn.close() print(f'用户{addr[0]},断开了连接。') clients.remove(conn) except BlockingIOError: pass
all_conn_data = clients

 IO多路复用之epoll(linux上效率最高的io复用技术)机制基于linux内核 :  (tornado封装了epoll,因此tornado适用于linux)

IO多路复用(epoll)

  注册事件

  等待事件被触发

  由操作系统监控

  惰性 非主动调用

  代码调用

import socket
import selectors


server = socket.socket()
epoll_selector = selectors.EpollSelector()

server.bind(('', 8888))
server.listen(5)


def server_recv(conn):
    recv_data = conn.recv(1024)
    if recv_data:
        print(recv_data)
        conn.send(recv_data)
    else:
        epoll_selector.unregister(conn)
        conn.close()


def server_conn(server):
    conn, addr = server.accept()
    epoll_selector.register(conn, selectors.EVENT_READ, server_recv)


epoll_selector.register(server, selectors.EVENT_READ, server_conn)


while True:
    events = epoll_selector.select()
    # print(events)  #[(SelectorKey(
                        # fileobj=<socket.socket fd=3,
                        # family=AddressFamily.AF_INET,
                        # type=SocketKind.SOCK_STREAM,
                        # proto=0, laddr=('0.0.0.0', 8888)>,
                        # fd=3, events=1,
                        # data=<function server_conn at 0xb72c16ec>), 1)]

    for event, n in events:
        file_obj = event.fileobj  # 套接字
        callbanck = event.data
        callbanck(file_obj)
原文地址:https://www.cnblogs.com/tangpg/p/10595741.html