用select模拟一个socket server
1, 必须在非阻塞模式下,才能实现IO的多路复用,否则一个卡住就都卡住了。(单线程下的多路复用)

先检测自己,现在没有客户端连进来,所以会卡住。
# 用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个的哪个有问题,就把有问题的返回。还是把100个放到这里。 server.accept() #没有链接也不阻塞,只是返回一个错误。
运行结果:
C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day10/ex3_Client.py
2. 客户端代码:
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()
服务器端:
# 用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 = []
readable,writeable,exceptional=select.select(inputs, outputs, inputs) # 第一个参数:需要检测哪些链接就放进来。操作系统发现100个里面有1个在活动,就会返回这100个。 # 第二个参数: # 第三个参数:让操作系统检测100个的哪个有问题,就把有问题的返回。还是把100个放到这里。 print(readable,writeable,exceptional) #新来的链接会出现在readable里面, server.accept() #没有链接也不阻塞,只是返回一个错误。
运行结果:fd=240 文件描述符
C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day10/ex3_Client.py
[<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] [] Process finished with exit code 0
3.
# 用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 = []
readable,writeable,exceptional=select.select(inputs, outputs, inputs) # 第一个参数:需要检测哪些链接就放进来。操作系统发现100个里面有1个在活动,就会返回这100个。 # 第二个参数: # 第三个参数:让操作系统检测100个的哪个有问题,就把有问题的返回。还是把100个放到这里。 print(readable,writeable,exceptional) #新来的链接会出现在readable里面, for r in readable:
conn,addr=server.accept() #没有链接也不阻塞,只是返回一个错误。
print(conn,addr)
客户端:
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()
运行结果:
C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:\abccdxddd\Oldboy\Py_Exercise\Day10\select_socket_server2.py
[<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] []
<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', 49587)> ('127.0.0.1', 49587) Process finished with exit code 0
至此链接已经建立。
4.最终版本
服务器端:
import select,socket
server=socket.socket()
server.bind(('localhost',9000))
server.listen(1024) #最多可以监听1024个
server.setblocking(False)
inputs=[server,]
outputs=[]
while True:
readable,writeable,exceptional=select.select(inputs,outputs,inputs) #select帮着去检测这100个链接
print(readable,writeable,exceptional)
for r in readable:
if r is server:
conn,addr=server.accept()
print('来了个新链接',addr)
inputs.append(conn)
else:
data=r.recv(1024)
print('收到数据',data)
r.send(data)
客户端:
import socket
s=socket.socket()
s.connect(('localhost',9000))
while True:
msg=bytes(input(">>:"),encoding='utf8')
s.sendall(msg)
data=s.recv(1024)
print('Received',repr(data))
s.close()
运行结果:
C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day10/select_socket_server2.py
[<socket.socket fd=232, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] []
来了个新链接 ('127.0.0.1', 61118)
[<socket.socket fd=324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61118)>] [] []
收到数据 b'1'
[<socket.socket fd=324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61118)>] [] []
收到数据 b'2'
[<socket.socket fd=232, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000)>] [] []
来了个新链接 ('127.0.0.1', 61119)
[<socket.socket fd=328, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61119)>] [] []
收到数据 b'3'
[<socket.socket fd=328, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61119)>] [] []
收到数据 b'4'
[<socket.socket fd=324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61118)>] [] []
收到数据 b'7'
[<socket.socket fd=328, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 61119)>] [] []
收到数据 b'8'
一个server端,两个client端

用select模拟一个socket server的更多相关文章
- 用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 ...
- 用select (多路复用)模拟一个 socket server
需求:用select (多路复用)模拟一个 socket server.可以接收多并发. 1. 一开始是检测自己,如果我有活动了,就说明有客户端要连我了. #用select去模拟socket,实现单线 ...
- python利用select实现的Socket Server
# 利用python的select模块实现简单的Socket Sever #实现多用户访问,再次基础上可以实现FTP Server应用程序 # 发布目的,在于解决了客户端强行终止时,服务器端也跟着程序 ...
- C语言写了一个socket server端,适合windows和linux,用GCC编译运行通过
////////////////////////////////////////////////////////////////////////////////* gcc -Wall -o s1 s1 ...
- VFP 用 SPT 来发布一条 SELECT 到一个新的 SQL Server 表
为了发布一条 SQL SELECT 语句来创建一个新的 SQL Server 表, SQL Server 数据库的 select into/bulkcopy 选项必须是可用的. 在默认情况下, 对于 ...
- 面向连接的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通讯框架已经初具雏形了,那么我们接下来做的.就是想办法让这个框架更 ...
随机推荐
- 优步UBER司机全国各地奖励政策汇总 (2月1日-2月7日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- STM32F746G-DISCO官方例程烧写
1. 首先安装STM32 ST-LINK Utility v3.9.0.exe,必须V3.9版本(官方说的) 2. 打开软件,选择External Loader,选择N25Q128A_STM32F74 ...
- nodejs HTTP服务
nodejs中的HTTP服务 nodejs最重要的方面之一是具有非常迅速的实现HTTP和HTTPS服务器和服务的能力.http服务是相当低层次的,你可能要用到不同的模块,如express来实现完整 ...
- 一种精准monkey测试的方法
WeTest 导读 相信大家都知道移动端应用的monkey测试吧,不知你们有没有为monkey测试的太过于随机性的特性有过困扰,至少在我们这种界面控件较少且控件位置较偏的app的使用上其测试有效性大打 ...
- redmine本地安装部署
1.railsinstaller-3.2.0.exe 下载地址 http://railsinstaller.org/en 安装railsinstaller 一直点next就可以了,安装完成之后C盘会 ...
- 第三篇 JavaScript基础
知识预览 BOM对象 DOM对象(DHTML) 实例练习 转:https://www.cnblogs.com/yuanchenqi/articles/5980312.html#_label2 一.Ja ...
- Resharp使用简记
一图流: 拾贝: .字符串引号中直接回车键自动添加连接字符串 Ctrl+B:转到定义 Ctr+F11:展示类结构 Ctr+Alt+j:包围代码块 Ctr+\:注释和取消注释 Alt+Ins:重构 Ct ...
- 机器学习介绍(introduction)-读书笔记-
一,什么是机器学习 第一个机器学习的定义来自于 Arthur Samuel.他定义机器学习为,在进行特定编程的情况下,给予计算机学习能力的领域.Samuel 的定义可以回溯到 50 年代,他编写了一个 ...
- Memcache的客户端连接系列(二) Python
关键词: Memcached Python 客户端 声明:本文并非原创,转自华为云帮助中心的分布式缓存服务(Memcached)的用户指南.客户端连接方法通用,故摘抄过来分享给大家. Python ...
- Python+Opencv实现把图片转为视频
1. 安装Opencv包 在Python命令行输入如下命令(如果你使用的Anaconda,直接进入Anaconda Prompt键入命令即可.如果你不知道Anaconda是什么,可以参考王树义老师的文 ...