用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, 超时时间) 参数: 可接受四个参数(前三个必须) 返回 ...
随机推荐
- 一分钟了解spark的调优
Tuning Spark 数据序列化 内存调优 内存管理概述 确定内存消耗 调整数据结构 序列化 RDD 存储 垃圾收集调整 其他注意事项 并行度水平 减少任务的内存使用 广播大的变量 数据本地化 概 ...
- getSteam
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...
- andriod学习一
1.Android软件栈 2.Android模拟器 Android SDK 可以通过ADT+Eclipse或者命令行开发,调试,测试应用程序,设备可以使用模拟器或者真实设备, ...
- python学习五
打包代码与数据 数据结构要与数据匹配,数据结构影响代码的复杂性 列表 集合 字典 #创建与初始化 cleese={} cleese2=dict() cleese["name"] ...
- 了解Python控制流语句——for 循环
for 循环 Python教程中for...in 语句是另一种循环语句,其特点是会在一系列对象上进行迭代(Iterates),意即它会遍历序列中的每一个项目.我们将在后面的Python序列(Seque ...
- C 计算时间差
#include <stdio.h>int main(){ //新建四个变量 la 代表小时 kc代表时间 int l,k,a,c; //输入 两个时间 scanf("%d %d ...
- 几个常见移动平台浏览器的User-Agent
之前介绍的手机站跳转url的一片文稿中提到,依据User Agent判断终端的方法.(文章地址:http://www.cnblogs.com/dereksunok/p/3664169.html ) 若 ...
- Ext JS 6学习文档-第3章-基础组件
Ext JS 6学习文档-第3章-基础组件 基础组件 在本章中,你将学习到一些 Ext JS 基础组件的使用.同时我们会结合所学创建一个小项目.这一章我们将学习以下知识点: 熟悉基本的组件 – 按钮, ...
- 有道云笔记Markdown使用
目录 使用规则 代码高亮 制作待办事项 高效绘图 基本规则 使用规则 代码高亮 #include <iostream> #include <string> using name ...
- es6从零学习(三):Class的基本用法
es6从零学习(三):Class的基本用法 一:定义一个类 //定义类 class Point { constructor(x, y) { this.x = x; this.y = y; } toSt ...