day39,IO模型
作者:互联网
IO模型
模型就是解决某个问题的套路
IO问题:
输入输出
我要一个用户名用来执行登陆操作,问题用户名需要用户输入,输入需要耗时, 如果输入没有完成,后续逻辑无法继续,所以默认的处理方式就是 等
将当前进程阻塞住,切换至其他进程执行,等到按下回车键,拿到了一个用户名,再唤醒刚才的进程,将状态调整为就绪态
以上处理方案 就称之为阻塞IO模型
存在的问题:
当执行到recv时,如果对象并没有发送数据,程序阻塞了,无法执行其他任务
解决方案:
多线程或多进程,
当客户端并发量非常大的时候,服务器可能就无法开启新的线程或进程,如果不对数量加以限制 服务器就崩溃了
线程池或进程池
首先限制了数量 保证服务器正常运行,但是问题是,如果客户端都处于阻塞状态,这些线程也阻塞了
协程:
使用一个线程处理所有客户端,当一个客户端处于阻塞状态时可以切换至其他客户端任务
非阻塞IO模型
阻塞IO模型在执行recv 和 accept 时 都需要经历wait_data
非阻塞IO即 在执行recv 和accept时
不会阻塞 可以继续往下执行
如何使用:
将server的blocking设置为False 即设置非阻塞
存在的问题 :
这样一来 你的进程 效率 非常高 没有任何的阻塞
很多情况下 并没有数据需要处理,但是我们的进程也需要不停的询问操作系统 会导致CPU占用过高
而且是无意义的占用
import socket server = socket.socket() server.bind(('192.168.13.143',666)) server.setblocking(False) server.listen(5) clients = [] while True: try: client,addr = server.accept() clients.append(client) except BlockingIOError : print('还没有链接需要处理%s'%len(clients)) for i in clients[:]: try: data = i.recv(1024) i.send(data.upper()) print('已处理') except ConnectionResetError: clients.remove(i) except BlockingIOError: print('此客户无需处理')
import socket client = socket.socket() client.connect(('192.168.13.143',666)) while True: msg = ' i am is 大帅比'.encode('utf-8') client.send(msg) data = client.recv(1024) print(data.decode('utf-8'))
多路复用IO模型
import socket import select server = socket.socket() server.bind(('192.168.13.143',666)) server.listen() r_list = [server] w_list = [] datas = [] while True: readable_list,writeable_list,_ = select.select(r_list,w_list,[]) # print('当前可写socket客户端:%s,当前可读socket客户端%s'%(len(writeable_list),len(readable_list))) for soc in readable_list: if soc == server: client,addr = soc.accept() r_list.append(client) else: try: data = soc.recv(2048) if not data: r_list.remove(soc) soc.close() continue # soc.send(data.upper()) w_list.append(soc) datas.append((soc,data)) except ConnectionResetError: print('对方强制关闭了') r_list.remove(soc) w_list.remove(soc) soc.close() continue print('当前可写socket客户端:%s,当前可读socket客户端%s' % (len(writeable_list), len(readable_list))) for soc in writeable_list[:]: for i in [i for i in datas if i[0] == soc]: soc.send(i[1].upper()) datas.remove(i) w_list.remove(soc)
import socket import time client = socket.socket() client.connect(('192.168.13.143',666)) while True: msg = ' i am is 大帅比'.encode('utf-8') # msg = input('msg:').encode('utf-8') client.send(msg) # time.sleep(10) data = client.recv(1024) print(data.decode('utf-8'))
标签:soc,socket,day39,模型,list,server,client,IO,data 来源: https://www.cnblogs.com/jixu/p/11000047.html