网络编程之I/O复用模型select
来源:互联网 发布:淘宝店掌柜名怎么修改 编辑:程序博客网 时间:2024/05/21 09:13
#Author :ywqimport selectimport socketimport queueserver = socket.socket()server.bind(('localhost',9000))server.listen(1000)server.setblocking(False) #不阻塞msg_dic = {}inputs = [server,]#inputs = [server,conn] #[conn,]#inputs = [server,conn,conn2] #[conn2,]outputs = [] ##outputs = [r1,] #while True: readable ,writeable,exceptional= select.select(inputs, outputs, inputs ) print('Readable:',readable,) print('writable:',writeable) print('exception:',exceptional) print('input:',inputs) for r in readable: if r is server: #代表来了一个新连接 conn,addr = server.accept() print("来了个新连接",conn) inputs.append(conn) #是因为这个新建立的连接还没发数据过来,现在就接收的话程序就报错了 #所以要想实现这个客户端发数据来时server端能知道,就需要让select再监测这个conn msg_dic[conn] = queue.Queue() #初始化一个队列,后面存要返回给这个客户端的数据 #print(msg_dic) else: #conn2 data = r.recv(1024) print("收到数据",data) msg_dic[r].put(data) outputs.append(r) #放入返回的连接队列里 # r.send(data) # print("send done....") for w in writeable: #要返回给客户端的连接列表 data_to_client = msg_dic[w].get() w.send(data_to_client) #返回给客户端源数据 outputs.remove(w) #确保下次循环的时候writeable,不返回这个已经处理完的连接了 for e in exceptional: if e in outputs: outputs.remove(e) inputs.remove(e) del msg_dic[e] print('Readable:',readable,) print('writable:',writeable) print('exception:',exceptional) ''' 1.select.select(rlist,wlist,xlist)运行后生成三个列表,对应变量readable,writeable,exceptional, 三个变量类型也均为list。 2.三个参数:rlist, wlist, xlist,分别代表需要使用select监控的三个装有fd、socket fd的列表, select会监控列表里的fd,一旦传入的参数rlist内有可读的fd对象,则将该对象加入readable变量中。 一旦传入的参数wlist列表中有可写的fd对象,则将该对象加入writeable变量中, 一旦传入的参数xlist列表中有可连接error报错的fd对象,则将该对象加入exceptional变量中。 3.首先要把服务端socket加入inputs内让socket监控它,一旦服务端变为可读状态,即代表有新连接进来了(此时连接还未建立成功) 开始循环,遍历readable、writeable、exceptional三个列表,列表有数据则运行相应指令 与客户端连接建立后,应将客户端socket加入inputs列表,socket监控其是否可读、是否连接报错,此时刚刚建立连接,服务端 还不能直接socket.recv(1024),否则会报错,因为客户端消息还没发过来,要等待下一次循环。 连接建立后,进入下一轮循环,此时需等待客户端传消息过来,传消息过来后,if not is server,则执行else语句, 接收client端传来的消息,并且把client socket加入outputs列表,socket监控其是否可写,并且创建客户端专属队列, 准备开始传消息 4.进入for in writeable的循环,检测发现客户端已经是可写状态了,则开始传送数据。其实writeable也可以监控inputs列表 不用单独创建outputs列表,毕竟所有的连接socket都已经在inputs里边了,但是为了使遍历writeable列表速度更快, 最好把可写列表单独出来,节省资源。 5.总结:select的本质就是为了替程序快速监控fd、socket的I/O状态,以便根据I/O状态快速开始操作,可读可写时则 开始I/O操作,线程去执行其他计算操作。I/O操作时不消耗计算资源。以此交错开来尽量合理化地利用单线程资源。 '''
一个简单的echo server,使用select I/O复用模型,可以实现多并发连接请求的同时低资源消耗。
阅读全文
0 0
- Linux网络编程---I/O复用模型之select
- 网络编程之I/O复用模型select
- Unix Socket编程--I/O复用之select模型
- Unix Socket编程--I/O复用之select模型
- Unix Socket编程--I/O复用之select模型
- linux编程---网络编程之复用I/O模型
- WIN网络编程-select(I/O模型)
- I/O复用模型之select
- I/O复用之select模型
- Linux网络编程---I/O复用模型之poll
- Linux网络编程---I/O复用模型之epoll
- WinSock I/O编程模型之——Select模型
- linux网络编程之socket(八):五种I/O模型和select函数简介
- linux网络编程之socket(八):五种I/O模型和select函数简介
- linux网络编程之socket(八):五种I/O模型和select函数简介
- linux网络编程之socket(八):五种I/O模型和select函数简介
- I/O复用模型之select学习
- 网络编程模型综述 之 UNIX网络I/O模型
- win32 API界面编程---窗口
- vue组件之间的数据通讯小例子
- 从上往下打印二叉树 (剑指Offer 第 21 题)
- 《Cognitive Mapping and Planning for Visual Navigation》读书笔记
- 欢迎使用CSDN-markdown编辑器
- 网络编程之I/O复用模型select
- php面向对象方法实例(详细)
- 大数据正式9
- java 字符串截取的几种方式
- JAVA作业 简单的计算器
- 黑马商城项目_商品展示结构设计
- planarity安装
- C语言实验——两个数比较
- 虚析构函数