各类IO模型

多路复用IO模型

server 端

from socket import *
import select
import time
s = socket()
s.bind(('127.0.0.1',8001))
s.listen()

data_dict= {}
r_list=[s]
w_list=[]

while 1:
    readables,writables,_= select.select(r_list,w_list,[])

    for i in readables:
        print(i)
        if i == s:
            c,addr = i.accept()
            r_list.append(c)
        else:
            try:
                data = i.recv(1024)
                if not data:
                    i.close()
                    r_list.remove(i)
                    continue

                w_list.append(i)
                data_dict[i]=data
            except:
                print('强行下线')
                i.close()
                r_list.remove(i)


    for i in writables:
        try:
             i.send(data_dict[i].upper())
        except:
            i.close()
        finally:
            data_dict.pop(i)
            w_list.remove(i)


client 端

import socket

c = socket.socket()
c.connect(("127.0.0.1", 9999))
print("connect....")

while True:
    msg  = input(">>>:").strip()

    if not msg:continue
    c.send(msg.encode("utf-8"))

    data = c.recv(1024)
    print(data.decode("utf-8"))

**

阻塞IO模型

**
server端

import socket
from threading import Thread
s = socket.socket()
s.bind(("127.0.0.1",9999))
s.listen()


def talking(c):
    while True:
        try:
            data = c.recv(1024)
            print("recv.....")
            if not data:
                c.close()
                break
            # send是一个本地io操作 速度非常快
            c.send(data.upper())
        except ConnectionResetError:
            c.close()
            break

while True:
    c,addr = s.accept()
    print("accept.....")
    t = Thread(target=talking,args=(c,))
    t.start()

client端



import socket
import os
c = socket.socket()
c.connect(("127.0.0.1", 9999))
print("connect....")

while True:
    msg  = "%s 发来问候 hello" % os.getpid()
    if not msg:continue
    c.send(msg.encode("utf-8"))
    data = c.recv(1024)
    print(data.decode("utf-8"))


非阻塞IO模型

server端

"""
    非阻塞IO  即遇到IO操作也不导致程序阻塞,会继续执行
    意味着即使遇到IO操作CPU执行权也不会被剥夺
    程序效率就变高了

    以下程序 占用CPU太高
    原因是 需要无限的循环 去向操作系统拿数据

"""
import socket
import time
s = socket.socket()
s.bind(("127.0.0.1",9999))
s.listen()
# 设置socket 是否阻塞 默认为True
s.setblocking(False)

# 所有的客户端socket
cs = []
# 所有需要返回数据的客户端
send_cs = []

while True:
    # time.sleep(0.2)
    try:
        c,addr = s.accept() # 三次握手
        print("run accept")
        cs.append(c) #存储已经连接成功的客户端
    except BlockingIOError:
        # 没有数据准备 可以作别的事情
        # print("收数据")
        for c in cs[:]:
            try:
                data = c.recv(1024)
                if not data:
                    c.close()
                    cs.remove(c)
                print(data.decode("utf-8"))
                # 把数据和连接放进去
                send_cs.append((c, data))
                #c.send(data.upper()) # io
                # send也是io操作  在一些极端情况下 例如系统缓存满了 放不进去 那肯定抛出
                # 非阻塞异常  这时候必须把发送数据 单独拿出来处理 因为recv和send都有可能抛出相同异常
                # 就无法判断如何处理


            except BlockingIOError:
                continue

            except ConnectionResetError:
                c.close()
                # 从所有客户端列表中删除这个连接
                cs.remove(c)

        # print("发数据")
        for item in send_cs[:]:
            c,data = item
            try:
                c.send(data.upper())
                # 如果发送成功就把数据从列表中删除
                send_cs.remove(item)
            except BlockingIOError: # 如果缓冲区慢了 那就下次再发
                continue
            except ConnectionResetError:
                c.close() # 关闭连接
                send_cs.remove(item) # 删除数据
                # 从所有客户端中删除这个已经断开的连接
                cs.remove(c)

client 端

import socket

c = socket.socket()
c.connect(("127.0.0.1", 9999))
print("connect....")

while True:
    msg  = input(">>>:").strip()

    if not msg:continue
    c.send(msg.encode("utf-8"))

    data = c.recv(1024)
    print(data.decode("utf-8"))

posted @ 2019-03-12 20:34  不会玩python  阅读(4)  评论(0编辑  收藏  举报