select 实现server I/O多路复用通信
- 非阻塞模式下客户端发生异常或服务器未处理完数据,就会立刻返回错误,不用等待
服务器端
- 建立连接
- 设置为非阻塞模式
import select,queue,socket server=socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('localhost',2223)) server.listen(5) server.setblocking(False)
- 使用select进行监测
inputs=[server,]#一开始要先监测server,知道是否建立连接 outputs=[]readable, writable, excetional = select.select(inputs, outputs, inputs) # select 进行监听
- 判断最开始inputs里是否是server,是的话表示建立了连接
if r is server:#表示建立连接conn,addr=server.accept()conn.setblocking(False)#非阻塞inputs.append(conn)#select监测连接过来的实例msg_dic[conn]=queue.Queue()#初始化一个队列,用于存放每一个连接的数据print('建立连接',addr)
- 不是代表客户端开始发送数据,服务器接收数据并放入之前初始化的队列中
data=r.recv(1024) print(data.decode()) msg_dic[r].put(data)#向队列中存入数据 if r not in outputs:outputs.append(r)
- 向客户端发送数据,发送完毕从队列中移除连接
for w in writable:try:next_msg = msg_dic[w].get_nowait()#从队列中取元素,不等待except queue.Empty:# print('output queue for', w.getpeername(), 'is empty') outputs.remove(w)else:# print('sending "%s" to %s' % (next_msg, w.getpeername()))w.send(next_msg)
- 异常处理
for e in excetional:#发生异常就将连接移除 inputs.remove(e)if e in outputs:outputs.remove(e)e.close()del msg_dic[e]#从队列中移除连接
服务器端完整代码
#select模拟socketserver import select,queue,socket server=socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('localhost',2223)) server.listen(5) server.setblocking(False) inputs=[server,]#一开始要先监测server,知道是否建立连接 outputs=[] msg_dic={} while True:readable, writable, excetional = select.select(inputs, outputs, inputs) # select 进行监听for r in readable:if r is server:#表示建立连接conn,addr=server.accept()conn.setblocking(False)#非阻塞inputs.append(conn)#select监测连接过来的实例'''新建立的连接还没发数据过来,现在就接收数据的话是空的,会报错,因此要让select监测每一个连接过来的连接,这样才知道客户端发送数据过来'''msg_dic[conn]=queue.Queue()#初始化一个队列,用于存放每一个连接的数据print('建立连接',addr)else:try:data=r.recv(1024)#不可以直接判断数据是否为空,因为客户端断开时服务器已经接收不到数据了#有数据发送过来print(data.decode())msg_dic[r].put(data)if r not in outputs:outputs.append(r) # 放入返回的连接队列里,下一次循环select检测的时候发给客户端except ConnectionResetError as e:#处理没有数据的情况,即服务器断开print(addr,' is close...')if r in outputs:#移除连接 outputs.remove(r)inputs.remove(r)r.close()del msg_dic[r]breakfor w in writable:try:next_msg = msg_dic[w].get_nowait()#从队列中取元素,不等待except queue.Empty:# print('output queue for', w.getpeername(), 'is empty') outputs.remove(w)else:# print('sending "%s" to %s' % (next_msg, w.getpeername())) w.send(next_msg)# outputs.remove(w)#从outputs中移除旧的连接for e in excetional:#发生异常就将连接移除 inputs.remove(e)if e in outputs:outputs.remove(e)e.close()del msg_dic[e]#从队列中移除连接
View Code
注:判断客户端是否断开时,要用捕获异常来处理,不能直接判断服务器接收的数据是否为空,因为此时客户端已经断开了,服务器无法接收数据了,会报ConnectionResetError
客户端完整代码
import socket client=socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('localhost',2223)) while True:cmd=input(">>>")if cmd=='':continueclient.send(cmd.encode())data=client.recv(1024)print(data.decode())
View Code
转载于:https://www.cnblogs.com/Aprilnn/p/9318306.html
select 实现server I/O多路复用通信相关推荐
- PHP socket多路复用通信demo
PHP socket多路复用通信demo server.php 服务端脚本 function server() {date_default_timezone_set('PRC'); //设置时区set ...
- select 实现类似多线程_linux进程通信--socket套接字(四)--多路IO转实现一个server对应多个client...
先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,股票基金定投,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题 一 why 在前 ...
- Linux下网络socket编程——实现服务器(select)与多个客户端通信
一.关于socket通信 服务器端工作流程: 调用 socket() 函数创建套接字 用 bind() 函数将创建的套接字与服务端IP地址绑定 调用listen()函数监听socket() 函数创建的 ...
- Zabbix如何实现Server和Agent的通信加密
一.加密介绍 1.总览 Zabbix版本从3.0之后,开始支持Zabbix server, Zabbix proxy, Zabbix agent, zabbix_sender and zabbix_g ...
- select poll epoll IO操作多路复用及猴子补丁
一:select(能监控数量有限,不能告诉用户程序具体那个连接有数据) select目前几乎所有的平台都支持,其良好的跨平台支持也是一个优点 select的缺点在于单个进程能够监控的文件描述的数量存在 ...
- 【C/S通信交互之Socket篇】Cocos2dx(Client)使用BSD Socket与Mina(Server)手机网游通信框架!
本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2dx/844.htm ...
- access select max_SQL Server 数据库设计--SELECT语句
在数据库中,使用最多的就是查询语句:SELECT 语句用于检索表中的数据.常用的查询语句格式如下: SELECT [DISTINCT] [TOP (n)] { * | select_list } FR ...
- Linux系统编程——I/O多路复用select、poll、epoll
参考:https://segmentfault.com/a/1190000003063859 Linux下的I/O复用与epoll详解:https://www.cnblogs.com/lojunren ...
- LinuxI/O多路复用转接服务器——select模型实现
LinuxI/O多路复用转接服务器--select模型实现 select函数 函数原型 参数和返回值 fd_set结构体 位操作函数 select实现实现I/O多路复用服务器 实现流程 程序实现 服务 ...
最新文章
- 使用 NSUserDefaults 存储字典的一个坑
- centos7 pe系统安装_老毛桃WinPE以ISO镜像模式安装CentOS7
- 一次性动态绑定多个droplistdown
- webpack打包vue文件报错,但是cnpm run dev正常,最后我只想说:是我太笨,还是webpack4.4版本太坑...
- 红外传感器_基于红外避障传感器控制无人机
- Qt Creator连接QNX设备
- supervisord管理进程详解
- mysql多实例分配空间_mysql多实例的配置
- 软件体系架构课下作业07
- 大学生创新项目认真投一篇中文核心的坎坷故事
- C++之文件操作探究(三):写文件——二进制文件
- 电子元器件篇—共模电感
- 惠普HP CQ40系列笔记本windows SP2/SP3系统安装声卡驱动问题解决!
- 知网HTML阅读是什么,HTML – 屏幕阅读器究竟是什么?我应该如何处理我的网站?...
- Gyro-3电子陀螺二次开发
- 中国烟草和水烟行业市场供需与战略研究报告
- 机器学习实践:非监督学习-8
- STUFF函数介绍及使用场景
- Intel Xeon Platinum 8269CY(Cascade Lake)处理器性能评测
- 基于Xware搭建树莓派远程下载服务