• 非阻塞模式下客户端发生异常或服务器未处理完数据,就会立刻返回错误,不用等待

服务器端

  • 建立连接
  • 设置为非阻塞模式
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多路复用通信相关推荐

  1. PHP socket多路复用通信demo

    PHP socket多路复用通信demo server.php 服务端脚本 function server() {date_default_timezone_set('PRC'); //设置时区set ...

  2. select 实现类似多线程_linux进程通信--socket套接字(四)--多路IO转实现一个server对应多个client...

    先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,股票基金定投,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题 一 why 在前 ...

  3. Linux下网络socket编程——实现服务器(select)与多个客户端通信

    一.关于socket通信 服务器端工作流程: 调用 socket() 函数创建套接字 用 bind() 函数将创建的套接字与服务端IP地址绑定 调用listen()函数监听socket() 函数创建的 ...

  4. Zabbix如何实现Server和Agent的通信加密

    一.加密介绍 1.总览 Zabbix版本从3.0之后,开始支持Zabbix server, Zabbix proxy, Zabbix agent, zabbix_sender and zabbix_g ...

  5. select poll epoll IO操作多路复用及猴子补丁

    一:select(能监控数量有限,不能告诉用户程序具体那个连接有数据) select目前几乎所有的平台都支持,其良好的跨平台支持也是一个优点 select的缺点在于单个进程能够监控的文件描述的数量存在 ...

  6. 【C/S通信交互之Socket篇】Cocos2dx(Client)使用BSD Socket与Mina(Server)手机网游通信框架!

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2dx/844.htm ...

  7. access select max_SQL Server 数据库设计--SELECT语句

    在数据库中,使用最多的就是查询语句:SELECT 语句用于检索表中的数据.常用的查询语句格式如下: SELECT [DISTINCT] [TOP (n)] { * | select_list } FR ...

  8. Linux系统编程——I/O多路复用select、poll、epoll

    参考:https://segmentfault.com/a/1190000003063859 Linux下的I/O复用与epoll详解:https://www.cnblogs.com/lojunren ...

  9. LinuxI/O多路复用转接服务器——select模型实现

    LinuxI/O多路复用转接服务器--select模型实现 select函数 函数原型 参数和返回值 fd_set结构体 位操作函数 select实现实现I/O多路复用服务器 实现流程 程序实现 服务 ...

最新文章

  1. 使用 NSUserDefaults 存储字典的一个坑
  2. centos7 pe系统安装_老毛桃WinPE以ISO镜像模式安装CentOS7
  3. 一次性动态绑定多个droplistdown
  4. webpack打包vue文件报错,但是cnpm run dev正常,最后我只想说:是我太笨,还是webpack4.4版本太坑...
  5. 红外传感器_基于红外避障传感器控制无人机
  6. Qt Creator连接QNX设备
  7. supervisord管理进程详解
  8. mysql多实例分配空间_mysql多实例的配置
  9. 软件体系架构课下作业07
  10. 大学生创新项目认真投一篇中文核心的坎坷故事
  11. C++之文件操作探究(三):写文件——二进制文件
  12. 电子元器件篇—共模电感
  13. 惠普HP CQ40系列笔记本windows SP2/SP3系统安装声卡驱动问题解决!
  14. 知网HTML阅读是什么,HTML – 屏幕阅读器究竟是什么?我应该如何处理我的网站?...
  15. Gyro-3电子陀螺二次开发
  16. 中国烟草和水烟行业市场供需与战略研究报告
  17. 机器学习实践:非监督学习-8
  18. STUFF函数介绍及使用场景
  19. Intel Xeon Platinum 8269CY(Cascade Lake)处理器性能评测
  20. 基于Xware搭建树莓派远程下载服务

热门文章

  1. 无线通信领域:技术整合,创造未来
  2. document.forms用法
  3. 共享卫士2.0版设置说明
  4. java中读取文件的方法
  5. 传说中的CAFEBABE到底在哪儿?
  6. Kafka 为什么那么快的 6 个原因!
  7. Linux 最常用命令:简单易学,但能解决 95% 以上的问题
  8. 996和被辞退,二选一
  9. Java8 中用法优雅的 Stream 性能也优雅吗?
  10. Java线程详解(9)-并发协作