用select (多路复用)模拟一个 socket server
需求:用select (多路复用)模拟一个 socket server。可以接收多并发。
1. 一开始是检测自己,如果我有活动了,就说明有客户端要连我了。
#用select去模拟socket,实现单线程下的多路复用 import select
import socket
import queue server=socket.socket()
server.bind(('localhost',9000))
server.listen(1024) server.setblocking(False) #设置为不阻塞,accept/recv没有数据都不阻塞,只会报错。 inputs=[server,] #先检测自己,如果我有活动了,说明有客户端要连我了。 outputs=[] select.select(inputs,outputs,inputs) #第一个参数:操作系统发现100个里面有1个在活动,就会返回这100个。需要检测哪些链接就放进来。 #第二个参数: #第三个参数:让操作系统检测100个的哪个有问题,就把有问题的返回。 server.accept()
运行结果:卡住了,有客户端进来时才会不卡。
C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day10/select_socket_server.py
2.服务器端
#用select去模拟socket,实现单线程下的多路复用
import select
import socket
import queue
server=socket.socket()
server.bind(('localhost',9000))
server.listen(1024)
server.setblocking(False) #设置为不阻塞,accept/recv没有数据都不阻塞,只会报错。
inputs=[server,] #先检测自己,如果我有活动了,说明有客户端要连我了。
#inputs=[server,conn]
outputs=[]
while True:
readable,writeable,exceptional=select.select(inputs,outputs,inputs)
#第一个参数:操作系统发现100个里面有1个在活动,就会返回这100个。需要检测哪些链接就放进来。
#第二个参数:
#第三个参数:让操作系统检测100个的哪个有问题,就把有问题的返回。
print(readable,writeable,exceptional)
for r in readable:
if r is server: #代表来了一个新链接
conn,addr=server.accept()
print('来了个新链接',addr)
inputs.append(conn) #是因为这个新建立的连接还没有发数据过来,现在就接收的话,程序会报错。
#所以要想实现这个客户端发数据来时server端能知道,就需要让select再监测这个Conn。
else:
data=conn.recv(1024)
print('收到数据',data)
conn.send(data)
客户端:
import socket
HOST = 'localhost' # The remote host
PORT = 9000 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
while True:
msg = bytes(input(">>:"), encoding="utf8")
s.sendall(msg)
data = s.recv(1024)
# print(data)
print('Received', repr(data)) #repr:格式化输出
s.close()
运行结果: 有2个链接的情况下,无法多次接收数据
C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day10/select_socket_server.py
[<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] []
来了个新链接 ('127.0.0.1', 53605)
[<socket.socket fd=336, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 53605)>] [] []
收到数据 b'1'
[<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] []
来了个新链接 ('127.0.0.1', 60337)
[<socket.socket fd=348, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 60337)>] [] []
收到数据 b'123'
3. server端进行修改:
#用select去模拟socket,实现单线程下的多路复用
import select
import socket
import queue
server=socket.socket()
server.bind(('localhost',9000))
server.listen(1024)
server.setblocking(False) #设置为不阻塞,accept/recv没有数据都不阻塞,只会报错。
inputs=[server,] #先检测自己,如果我有活动了,说明有客户端要连我了。
#inputs=[server,conn]
outputs=[]
while True:
readable,writeable,exceptional=select.select(inputs,outputs,inputs)
#第一个参数:操作系统发现100个里面有1个在活动,就会返回这100个。需要检测哪些链接就放进来。
#第二个参数:
#第三个参数:让操作系统检测100个的哪个有问题,就把有问题的返回。
print(readable,writeable,exceptional)
for r in readable:
if r is server: #代表来了一个新链接
conn,addr=server.accept()
print('来了个新链接',addr)
inputs.append(conn) #是因为这个新建立的连接还没有发数据过来,现在就接收的话,程序会报错。
#所以要想实现这个客户端发数据来时server端能知道,就需要让select再监测这个Conn。
else:
data=r.recv(1024)
print('收到数据',data)
r.send(data)
至此运行正常
用select (多路复用)模拟一个 socket server的更多相关文章
- 用select模拟一个socket server
1, 必须在非阻塞模式下,才能实现IO的多路复用,否则一个卡住就都卡住了.(单线程下的多路复用) 先检测自己,现在没有客户端连进来,所以会卡住. # 用select去模拟socket,实现单线程下的多 ...
- 用select模拟一个socket server成型版2
1.字典队列测试 import queue msg_dic={} msg_dic[1]=queue.Queue() msg_dic[1].put('hello') msg_dic[1].put('bo ...
- 用select模拟一个socket server成型版
1.你往output里面放什么,下次循环就出什么. 2. 1.服务器端:实现了收和发的分开进行 import select,socket,queue server=socket.socket() s ...
- C语言写了一个socket server端,适合windows和linux,用GCC编译运行通过
////////////////////////////////////////////////////////////////////////////////* gcc -Wall -o s1 s1 ...
- 面向连接的Socket Server的简单实现(简明易懂)
一.基本原理 有时候我们需要实现一个公共的模块,需要对多个其他的模块提供服务,最常用的方式就是实现一个Socket Server,接受客户的请求,并返回给客户结果. 这经常涉及到如果管理多个连接及如何 ...
- C#中自己动手创建一个Web Server(非Socket实现)
目录 介绍 Web Server在Web架构系统中的作用 Web Server与Web网站程序的交互 HTTPListener与Socket两种方式的差异 附带Demo源码概述 Demo效果截图 总结 ...
- [Golang] 从零開始写Socket Server(3): 对长、短连接的处理策略(模拟心跳)
通过前两章,我们成功是写出了一套凑合能用的Server和Client,并在二者之间实现了通过协议交流.这么一来,一个简易的socket通讯框架已经初具雏形了,那么我们接下来做的.就是想办法让这个框架更 ...
- 分析一个socket通信: server/client
分析一个socket通信: server/client1 server 1. 创建一个server_socket文件,并绑定端口,然后监听端口 (socket, bind, listen) 2. 查询 ...
- python16_day09【Select多路复用】
一.select多路复用 句柄列表11, 句柄列表22, 句柄列表33 = select.select(句柄序列1, 句柄序列2, 句柄序列3, 超时时间) 参数: 可接受四个参数(前三个必须) 返回 ...
随机推荐
- 北京Uber优步司机奖励政策(2月29日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- ORB-SLAM(十)LoopClosing Sim3求解
主要参考这篇论文 Horn B K P. Closed-form solution of absolute orientation using unit quaternions[J]. JOSA A, ...
- onenet基础通信套件加B300移植
1. 遇到的第一个问题,说是少了文件,但是明明有这个文件的啊? scons: warning: Ignoring missing SConscript 'build_scons\arm\Hi2115\ ...
- C# 组装XML传给webserver+XML 返回获取多个xml,根据多个XML 返回dataset类型
大致流程介绍: 传值给 webserver+XML ,得到webserver+XML多个返回值,组装成dataset形式返回 首先创建所需要的类型 DataSet ds = new DataSet() ...
- spring入门(Ioc的理解)
spring对依赖的注入理解可以参考这篇:https://www.cnblogs.com/alltime/p/6729295.html 依赖注入和控制反转 传统的JavaEE程序中,直接在内部new一 ...
- lintcode39 恢复旋转排序数组
恢复旋转排序数组 给定一个旋转排序数组,在原地恢复其排序. 您在真实的面试中是否遇到过这个题? Yes 说明 什么是旋转数组? 比如,原始数组为[1,2,3,4], 则其旋转数组可以是[1,2,3 ...
- 孤荷凌寒自学python第八十三天初次接触ocr配置tesseract环境
孤荷凌寒自学python第八十三天初次接触ocr配置tesseract环境 (完整学习过程屏幕记录视频地址在文末) 学习Python我肯定不会错过图片文字的识别,当然更重要的是简单的验证码识别了,今天 ...
- Laxcus大数据管理系统2.0(12)- 第十章 运行
第十章 运行 本章将介绍一些Laxcus集群基本运行.使用情况,结合图片和表格表示.地点是我们的大数据实验室,使用我们的实验集群.数据来自于我们的合作伙伴,软件平台混合了Windows和Fedora ...
- opencv-学习笔记(5)形态学转变
opencv-学习笔记(4)形态学转变 本章讲了几种形态学操作 腐蚀erode 膨胀dilate 开运算MORPH_OPEN 闭运算MORPH_CLOSE 形态学梯度MORPH_GRADIENT 礼帽 ...
- parity 注记词
spousal tint untold around rosy daintily unrated sheep choice showpiece chirping gala