#IO模型
#阻塞IO.(文件读写,print/input/sleep/json)
#阻塞流程
# python应用 内核
# ----->系统调用---->没有数据准备好
# \
# \等待
# \
# 数据准备好
# \
# \ copy
# 拿到数据 <------ 返回<---- copy完成
#并发:非阻塞IO(sk.setblocking(False))
# import socket
# sk = socket.socket()
# sk.bind(('127.0.0.1',9000))
# sk.listen()
#
# sk.setblocking(False)#默认为真,阻塞。为假以后下面的accept和recv都变为不阻塞。
#
# lis_c = [] #定义一个空列表,用来存放连接上的conn
# lis_r = [] #定义一个空列表,用来存放对方已经关闭的conn,因为不能在循环conn时直接关闭并删除。
# while True:
# try:
# conn , addr = sk.accept() #如果有客户端连接,走下一步,否则由于不阻塞,所以报错,走except.
# lis_c.append(conn) #将连入的客户端放入列表中。之后挨个循环聊天。
# except: #报错。代表暂时没有客户端连接。
# for con in lis_c:#循环已经连接上的conn
# try:
# con.send(b'hello') #如果对方正常开启,则正常发送。
# try:
# print(con.recv(1024)) #如果有接收的消息,正常接收
# except:pass #如果没有接收的消息,报错。pass掉。
# except: #如果对方已经关闭连接,此处发送不过去,报错。
# con.close() #关闭对方已经关闭的conn
# lis_r.append(con) #将此conn放入第二个列表中,for循环结束后再对其遍历然后从第一个列表中删除。
# for con in lis_r: #遍历第二个列表
# lis_c.remove(con) #对应删除第一个列表中的conn
# lis_r.clear() #第二个列表放的都是已经关闭的连接,没有用了,将其清空。
# sk.close()
#非阻塞IO中有很多while无限循环,没有数据接收的时候也无时无刻不在循环,大大占用了CPU的资源,非常耗CPU。
#解决:IO多路复用(用代理select使阻塞监听。),只要有一个数据准备好了就开始下一步。
# python应用 内核
# 代理(sk/conn1/conn2...) ---系统调用----> 没有数据准备好
# \
# \ 等待(阻塞、监听)
# sk:sk.accpet <---告诉是哪一个对象好了---- 数据准备好(只要有一个好了)
#conn:conn.recv \
# ---------------------------> copy数据
# \
# \ copy阶段
# 拿到数据 <----------返回------------------- copy完成
# import select
# import socket
#
# sk = socket.socket()
# sk.bind(('127.0.0.1',9000))
# sk.listen()
# sk.setblocking(False)
#
# rlst = [sk] #放入要监听的与读有关的对象
# wlst = [] #放入要监听的与写有关的对象
# xlst = [] #放入要监听的与异常有关的对象
#
# while True:
# rl, wl, xl = select.select(rlst, wlst, xlst) # 分别返回三个列表,rl中为返回的每一个对象。循环接收。
# for obj in rl: #只要有一个数据准备好了,就开始for循环返回的列表。
# if obj == sk: #如果是sk,就接收连接,并把得到的conn放入rlst中一起监听。
# conn,addr = sk.accept()
# rlst.append(conn)
# else: #如果不是sk肯定是conn.
# msg = obj.recv(1024) #如果是conn,肯定是recv,对方一定发送过来了消息。
# if msg == b'': #如果对方将客户端关闭,收到的一定是 b''.
# obj.close() #将conn关闭
# rlst.remove(obj) #并将其在监听列表中删除。
# continue #如果关闭则不接收或发送消息,不走下一步,回到循环最开始。
# else:
# print(msg) #如果对方没有关闭,把收到的消息打印出来
# obj.send(b'hello') #同时也可以对其发送消息。