IO多路复用

一、用非阻塞IO解决阻塞IO模型

  

import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
sk.setblocking(False)
lst = []
del_lst = []
while 1:
    try:
        conn,address = sk.accept()
        lst.append(conn)
    except BlockingIOError:
        for conn in lst:
            try:
                dat = conn.recv(1024).decode('utf-8')
                if not dat:
                    del_lst.append(conn)
                    print('客户端正常关闭')
                    conn.close()
                else:
                    print(dat)
                    conn.send(dat.upper().encode('utf-8'))
            except ConnectionResetError :
                continue
            except BlockingIOError:
                pass
        if del_lst:
            for i in del_lst:
                lst.remove(i)
            del_lst.clear()
sever_非阻塞IO解决IO阻塞
import socket
sk = socket.socket()
sk.connect(('127.0.0.1', 8080))
while 1:
    word = input('>>>')
    if word == 'q':
        break
    sk.send(word.encode('utf-8'))
    info = sk.recv(1024).decode('utf-8')
    print(info)

sk.close()
client_

二、基于select的IO多路模型

select  和  poll ,epoll

select 和 poll 有一个共同机制:都采用轮询的方式去访问内核,问数据有没有准备好。

select 有一个最大的监听事件的限制,32位机限制是1024,64位机限制是2048。

poll 没有,理论上pool可以开启无限大

epool 采用的是回调机制,解决了select 和 poll 的缺点

 二、用select解决IO阻塞

  代码:

  

import socket
import select

sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
rlist = [sk]
while 1:
    r, w, x = select.select(rlist, [], [])
    if r:
        for i in r:
            if i == sk:
                conn,address = i.accept()
                rlist.append(conn)
            else:
                try:
                    dat = i.recv(1024).decode('utf-8')
                    if not dat:
                        print('客户端正常关闭')
                        rlist.remove(i)
                        i.close()
                    else:
                        print(dat)
                        i.send(dat.upper().encode('utf-8'))
                except ConnectionResetError:
                    continue
服务器代码(select)
import socket
sk = socket.socket()
sk.connect(('127.0.0.1', 8080))
while 1:
    word = input('>>>')
    if word == 'q':
        break
    sk.send(word.encode('utf-8'))
    info = sk.recv(1024).decode('utf-8')
    print(info)

sk.close()
客户端代码(select)

原文地址:https://www.cnblogs.com/wf123/p/9551544.html