day 36 关于io模型的问题 阻塞 和多路复用

# from gevent import spawn,monkey;monkey.patch_all()
# from socket import *
# def server(ip,port):
# server = socket(AF_INET, SOCK_STREAM)
# server.bind((ip,port))
# server.listen(5)
#
# while True:
# conn, addr = server.accept()
# print(addr)
# # ....
# # t=Thread(target=talk,args=(conn,add))
# # t.start()
# spawn(talk,conn,addr)
# def talk(conn,addr):
# while True:
# try:
# data=conn.recv(1024)
# if not data:break
# conn.send(data.upper())
# except ConnectionResetError:
# break
# conn.close()
# if __name__ == '__main__':
# server('127.0.0.1',8080)
# --------------------------------------
# 题目 单线程下的 支持并发
# greenlet gevent 关于线程的
### spwan c产卵的意思 引用的这个monkey 必须放在最前
# yield能实现协程,不过实现过程不易于理解,greenlet是在这方面做了改进。
# greenlet 轻量级的并行编程 gevent封装了很多很方便的接口,其中一个就是monkey
# 服务端的
# from gevent import spawn,monkey;monkey.patch_all() ##patch 补丁 必须放在最前面
# from socket import *
# def server(ip,port):
# server=socket(AF_INET,SOCK_STREAM)
# server.bind((ip,port))
# server.listen(3)
# while True:
# conn,addr = server.accept()
# print(addr)
# spawn(talk,conn,addr)
# def talk(conn,addr):
# while True:
# try:
# data = conn.recv(1024)
# if not data: break
# conn.send(data.upper())
# except ConnectionResetError:
# break
# # conn.close()
# if __name__ == '__main__':
# server('127.0.0.1', 8881)
#
# # 客户端的
# from socket import *
# client = socket(AF_INET,SOCK_STREAM)
# client.connect(('127.0.0.1',8881))
# while True:
# client.send('hello'.encode('utf-8'))
# data = client.recv(1024)
# print(data.decode('utf-8'))

# # -----------------------------------------
# io 非阻塞服务端的模型
# from socket import *
# import time
# server = socket(AF_INET,SOCK_STREAM)
# server.bind(('127.0.0.1',8888))
# server.listen(3)
# server.setblocking(False) ##本身是阻塞的 但是参数为错 所以为非阻塞的意思
# conn_l =[]
# while True:
# try : ### 主要就是收集链接的任务
# conn,addr = server.accept()
# conn_l.append(conn) ##收到客户端的链接 地址 ,把链接放到列表里
# print(addr)
#
# except BlockingIOError: ##报错异常 没有链接 就会出现 主要的任务就是在收集链接的空闲
# ##去干通信的任务,消除io的等待
# print('没有接收链接,干点别的事')
# del_l=[]
# for conn in conn_l:
# try:
# data = conn.recv(1024)
# if not data:
# conn.close()
# del_l.append(conn)
# continue
# conn.send(data.upper())
# except BlockingIOError:
# pass
# except ConnectionResetError:
# conn.close()
# del_l.append(conn)
# for conn in del_l:
# conn_l.remove(conn) ####注意 原来的列表 不能直接删除元素 但是元列表在完成后 可以循环另一个列表的元素就删除掉
# ---------------------------
# io 多路复用的 引用selet 里面有三个列表 读写x
from socket import *
import time
import select
server = socket(AF_INET,SOCK_STREAM)
server.bind(('127.0.0.1',8880))
server.listen(2)
server.setblocking(False)## 设置为io复用
read_l=[server,]
print('starting')
while True:
r1,w1,x1 = select.select(read_l,[],[])
## 此时 r1就是read_l
for r in rl:
if r is server:
conn,addr = rl[0].accept()
print(addr)
read_l.append(conn)
else:
try:
data = r.recv(1024)
if not data:
r.close()
read_l.remove(r)
continue
r.send(data.upper())
except ConnectionResetError:
r.close()
read_l.remove(r)
原文地址:https://www.cnblogs.com/xiaoluoboer/p/7994727.html