python自动化开发学习 I/O多路复用
python自动化开发学习 I/O多路复用
一. 简介
socketserver在内部是由I/O多路复用,多线程和多进程,实现了并发通信。IO多路复用的系统消耗很小。
IO多路复用底层就是监听socket对象内部是否有变化,是否在收发消息,Python中select模块提供了select poll epoll 三种方式来实现IO多路复用,支持不同的操作系统。
windows : 提供select
Mac : 提供select
Linux : 提供select, poll, epoll
(1)select简介:
select 默认会将每一个变化的socket加入一个他自己维护的列表中,但是并不会明确是哪一个socket,它内部其实是通过一个for循环遍历整个列表,当列表中的socket很多的时候,for循环就会浪费资源。select默认可以监听1024个链接,它是由linux在同文件中定义的,可修改。select不是安全的线程,如果你把一个socket加入到select中,突然另外一个线程关闭了这个socket,那么接下来select的行为是随机的。
(2)poll简介:
poll修复了select的一些问题,例如去掉了1024个链接限制,想要监听多少都可以,poll不在修改传入的数组,但是poll依然不是线程安全的。
(3)epoll简介:
epoll不仅会告诉你socket组里面的数据,还会告诉你具体哪个socket有数据,无需自己寻找。而且epoll终于是线程安全的了。然而epoll局限于
Linux操作系统。
二 . 应用
select 方法
|
1
2
3
4
5
6
7
8
9
10
|
句柄列表11, 句柄列表22, 句柄列表33 = select.select(句柄序列1, 句柄序列2, 句柄序列3, 超时时间)<br>参数: 可接受四个参数(前三个必须)返回值:三个列表 select方法用来监视文件句柄,如果句柄发生变化,则获取该句柄。1、当 参数1 序列中的句柄发生可读时(accetp和read),则获取发生变化的句柄并添加到 返回值1 序列中2、当 参数2 序列中含有句柄时,则将该序列中所有的句柄添加到 返回值2 序列中3、当 参数3 序列中的句柄发生错误时,则将该发生错误的句柄添加到 返回值3 序列中4、当 超时时间 未设置,则select会一直阻塞,直到监听的句柄发生变化 当 超时时间 = 1时,那么如果监听的句柄均无任何变化,则select会阻塞 1 秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。 |
(1)监听客户端连接
服务端
import socket
import select
sk = socket.socket()
sk.bind(("127.0.0.1", 9999,))
sk.listen(5)
while True:
rlist, w, e = select.select([sk, ], [], [], 5)
# 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为[sk]
# 监听conn对象,如果conn发生变化,表示客户端有消息发送过来了,此时rlist的值为[客户端]
print(rlist)
for r in rlist:
print(r)
conn, address = r.accept()
conn.sendall(bytes("hello", encoding="utf-8"))
服务端
客户端
import socket
sk = socket.socket()
sk.connect(("127.0.0.1", 9999,))
data = sk.recv(1024)
print(data)
while True:
input(">>")
sk.close()
客户端
(2)监听客户端连接及接受客户端发送的数据
import socket
import select
sk = socket.socket()
sk.bind(("127.0.0.1", 9999,))
sk.listen(5) inputs = [sk,]
while True:
rlist, w, e = select.select(inputs, [], [], 1)
# 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为[sk]
# 监听conn对象,如果conn发生变化,表示客户端有消息发送过来了,此时rlist的值为[客户端]
print(len(inputs), len(rlist))
for r in rlist:
print(r)
if r == sk:
# 有新的客户端连接进来
conn, address = r.accept()
inputs.append(conn)
conn.sendall(bytes("hello", encoding="utf-8"))
else:
# 有客户端给我发送数据
recv_data = r.recv(1024)
print(recv_data)
服务端
import socket
sk = socket.socket()
sk.connect(("127.0.0.1", 9999,))
data = sk.recv(1024)
print(data)
while True:
inp = input(">>")
sk.sendall(bytes(inp, encoding='utf-8'))
sk.close()
客户端
(3)读写分离
import socket
import select
sk = socket.socket()
sk.bind(("127.0.0.1", 9999,))
sk.listen(5) inputs = [sk,]
outputs = []
while True:
rlist, wlist, e = select.select(inputs, outputs, [], 1)
# 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为[sk]
# 监听conn对象,如果conn发生变化,表示客户端有消息发送过来了,此时rlist的值为[客户端]
print(len(inputs), len(rlist))
for r in rlist:
print(r)
if r == sk:
# 有新的客户端连接进来
conn, address = r.accept()
inputs.append(conn)
conn.sendall(bytes("hello", encoding="utf-8"))
else:
# 有客户端给我发送数据
try:
recv_data = r.recv(1024)
if not recv_data: # 某些操作系统,在socket断开的时候,会发送一个空给server,所以要判断空的情况
raise Exception("断开连接")
else:
outputs.append(r)
except Exception as e:
inputs.remove(r)
for w in wlist:
w.sendall(bytes("response", encoding="utf-8"))
outputs.remove(w)
服务端
import socket
sk = socket.socket()
sk.connect(("127.0.0.1", 9999,))
data = sk.recv(1024)
print(data)
while True:
inp = input(">>")
sk.sendall(bytes(inp, encoding='utf-8'))
print(sk.recv(1024))
sk.close()
客户端
(4)读写分离之服务端根据客户端的输入返回对应的信息
import socket
import select
sk = socket.socket()
sk.bind(("127.0.0.1", 9999,))
sk.listen(5) inputs = [sk, ] #
outputs = []
messages = {} # 用来存放客户端发送过来的消息,存放格式 连接客户端的对象: 消息
while True:
rlist, wlist, elist = select.select(inputs, outputs, [sk, ], 1)
# rlist 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为[sk]
# wlist 监听conn对象,如果conn发生变化,表示客户端有消息发送过来了,此时rlist的值为[客户端]
# elist 监听sk(服务器端)对象是否发生错误
print(len(inputs), len(rlist))
for r in rlist:
print(r)
if r == sk:
# 有新的客户端连接进来
conn, address = r.accept()
inputs.append(conn)
messages[conn] = [] # 在存储消息的字典中创建一个以客户端连接对象为key 空列表为value的键值对
conn.sendall(bytes("hello", encoding="utf-8"))
else:
# 有客户端给我发送数据
try:
recv_data = r.recv(1024)
if not recv_data: # 某些操作系统,在socket断开的时候,会发送一个空给server,所以要判断空的情况
raise Exception("断开连接")
else:
outputs.append(r)
messages[r].append(recv_data)
except Exception as e:
inputs.remove(r)
del messages[r]
for w in wlist:
print(messages[w])
msg = messages[w].pop()
resp = msg + bytes("response", encoding="utf-8")
w.sendall(resp)
outputs.remove(w)
服务端
python自动化开发学习 I/O多路复用的更多相关文章
- python自动化开发学习 进程, 线程, 协程
python自动化开发学习 进程, 线程, 协程 前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...
- Python自动化开发学习20-Django的form组件
武沛齐老师的Django的FORM组件:http://www.cnblogs.com/wupeiqi/articles/6144178.html 转自:http://blog.51cto.com/st ...
- 《Python Web开发学习实录》高清PDF版|百度网盘免费下载|Python Web开发学习实录
<Python Web开发学习实录>高清PDF版|百度网盘免费下载|Python Web开发学习实录 提取码:9w3o 内容简介 Python是目前流行的动态脚本语言之一. 李勇,本书共1 ...
- python web 开发学习路线
转载,备着 自己目前学习python web 开发, 经过两个月的摸索,目前对web开发有了浅显的认识,把自己的学习过程贴出来.1.python入门推荐老齐<从零开始学python>,&l ...
- Selenium2+python自动化(学习笔记3)
1.加载firefox配置 参考代码: # coding=utf-8from selenium import webdriver# 配置文件地址,打开Firefox点右上角设置--帮助--故障排除信息 ...
- Python自动化开发-简介
1.Python简介 Python创始人 Guido Van Rossum,人称"龟叔",1989年圣诞节期间,为了在阿姆斯特丹打发时间,开发的一个新的脚本解释程序 作为ABC语 ...
- python自动化开发-1
1.python简介 python是一门简明并且强大的面向对象的开发语言,已经在WEB开发,软件开发,科学计算,大数据分析,自动化运维等领域得到了广泛的应用. 注意:所有测试均已python3为主,与 ...
- 写给深圳首期Python自动化开发周未班的信
你是否做了正确的决定? 深圳首期周未班的同学们大家好,我是Alex, 老男孩教育的联合创始人,Python项目的发起人,51CTO学院连续2届最受学员喜爱的讲师,中国最早一批使用Python的程序员, ...
- python自动化开发-[第九天]-异常处理、进程
今日概要: 1.异常处理使用 2.进程 3.paramiko模块使用 一.异常处理 1.常见的错误异常 #错误异常一 print(a) #NameError #错误异常二 int('sdadsds') ...
随机推荐
- 【Python+selenium】之奇怪问题总结
问题1: <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'> Time Elapsed: 0:00:04 ...
- RecyclerView 踩坑
一.RecyclerView设置拖动后怎么监听拖动的开始和结束 ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Cal ...
- shell遍历文件目录,监听文件变化,拼接字符串
最近利用业余时间学习了shell 并做了个例子 实现的功能是 : 监听demo文件夹下的文件,只要新增了 .js的文件就把对应的文件名重组,拼接, 最后写入到demo.js里面. 文件结构如下 : ...
- 已备份数据库的磁盘结构版本号为611,server支持版本号为539,无法还原或升级数据库
提供的是bak文件是2005备份的,还原到本地的sqlserver2000,提示:已备份数据库的磁盘上结构版本号为611.服务器支持版本号539,无法还原或升级数据库. 网上找了下,原因是611是sq ...
- mysql数据库的导出与导入
导出 在dos节目,切换到mysql依照文件夹的bin下.输入下面命令 mysqldump -u root -p nxu_life > nxu_life2.sql 运行完毕后.就能够看到在bin ...
- Selenium+C#自动化脚本开发学习
1:Selenium中对浏览器的操作 首先生成一个Web对象 IWebDriver driver = new FirefoxDriver(); //打开指定的URL地址 driver.Navigate ...
- 【BZOJ2460】[BeiJing2011]元素 贪心+高斯消元求线性基
[BZOJ2460][BeiJing2011]元素 Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法 ...
- zipkin环境搭建
基于jdk1.8 下载zipkin jar包 用wget下载zipkin官方最新jar包 wget -O zipkin.jar 'https://search.maven.org/remote_con ...
- A vectorized example
http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture4.pdf
- 启动/关闭Spring boot服务脚本
启动Spring boot服务脚本 #!/bin/bash cd /test java -jar test.jar &> ./test.log & echo "成功&q ...