https://www.cnblogs.com/zingp/p/6863170.html 

一:IO模型介绍

IO发生时涉及的对象和步骤

  对于一个网络IO(network IO),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)

  当一个read操作发生时,该操作会经历两个阶段:

  1)等待数据准备 (Waiting for the data to be ready)

  2)将数据从内核拷贝到进程中(Copying the data from the kernel to the process)

  记住这两点很重要,因为这些IO模型的区别就是在两个阶段上各有不同的情况

 

  1 import socket
2 server=socket.socket()
3 server.bind(("localhost",6969))
4 server.listen()
5 print("等待用户链接")
6 while True:
7 conn,addr=server.accept()
8 while True:
9 conn.send(("%s have connected to server"%addr).encode())
10 data=conn.recv(1024)
11 print("from client",data.decode())
12
13
14 import socket
15 client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
16 client.connect(("localhost",6969))
17 while True:
18 data=client.recv(1024)
19 print("from server:",data.decode())
20 client.send("hellow".encode())

阻塞IO

 import socket,time
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(("localhost",6969))
server.listen()
server.setblocking(False)#设置为非阻塞,默认为阻塞
print("等待用户链接")
while True:
try:
conn,addr=server.accept()
conn.send("you have connected to server".encode())
data=conn.recv(1024)
print("from client",data.decode())
conn.close()
except Exception as e:
print(e)
time.sleep(4)
##########
import socket,time
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
while True:
client.connect(("localhost", 6969))
data=client.recv(1024)
print("from server:",data.decode())
client.send("hellow".encode())
time.sleep(2)
break

非阻塞IO

由于设置了非阻塞IO(setblocking())所以在accept()的时候会报错,因为抓住了错误,所以开始会输出错误信息 ,有个问题就是服务端接收不到了客户端的数据

IO multiplexing:包括select,epoll,有些地方也称这种IO方式为event driven IO

注意1:select函数返回结果中如果有文件可读了,那么进程就可以通过调用accept()或recv()来让kernel将位于内核中准备到的数据copy到用户区

一:流程

二:IO多路复用的触发方式

  • 水平触发
  • 边缘触发

三:select实例

 import socket
import select
server=socket.socket()
server.bind(("localhost",6969))
server.listen()
while True:
r,w,e=select.select([server,],[],[],5)
#rlist -- wait until ready for reading
#wlist -- wait until ready for writing
#xlist -- wait for an ``exceptional condition''
#阻塞等待链接的时间
for i in r:
print(r)
conn,addr=i.accept()
print(conn)
print(addr)
print("hellow")
print(">>>>>")
#################### import socket,time
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
while True:
client.connect(("localhost", 6969))
print(client)
data=client.recv(1024)
print("from server:",data.decode())
client.send("hellow".encode())

select实现IO多路复用

在不调用accept的时候,会反复的输出hellow和>是因为select的触发方式为水平触发

 import select,socket
server=socket.socket()
server.bind(("localhost",6969))
server.listen(5)
inp=[server,]
while True:
r, w, e = select.select(inp, [], [])
for obj in r:
if obj == server:
print("r:", r)
print(len(r))
print(obj)
conn, addr = obj.accept()
inp.append(conn)
else:
print("obj:",obj)
data=obj.recv(1024).decode()
print(">>:",data)
data=input("回答%s:"%str(addr))
obj.send(data.encode())
###################################
import socket
client=socket.socket()
client.connect(("localhost",6969))
print(client)
while True:
inp=input(">>>>:")
client.send(inp.encode())
data=client.recv(1024).decode()
print(data)

select实现监听多链接

异步IO全程无阻塞

 import selectors
import socket
def accept(server,mask):
conn,addr=server.accept()
print("client_sock:%s\nclient_addr:%s"%(conn,addr))
sel.register(conn,selectors.EVENT_READ,read)#注册,将conn和read函数绑定
def read(conn,mask):
try:#window如果客户端断开链接会报错,但是如果是linux客户端断开会发空数据,检测断开手段不一样
data=conn.recv(1024)
print(data.decode())
conn.send(data)
except Exception as e:
print("close:%s"%conn)
sel.unregister(conn)#解除绑定
conn.close()
if __name__ == '__main__': sel=selectors.DefaultSelector()#生成一个selector的对象
print("sel:",sel)
server=socket.socket()
server.bind(("localhost",6969))
server.listen()
sel.register(server,selectors.EVENT_READ,accept)#注册,将server与accept绑定
while True:
events=sel.select()#相当于select.select()#检测是否有链接或已连接的socket是否发送数据
print("events:",events)
print("\n")
for key,mask in events:
print("key:",type(key),key)#(SelectorKey(fileobj=<socket.socket fd=536, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 6969)>, fd=536, events=1, data=<function accept at 0x02C14E40>)
callback=key.data
callback(key.fileobj,mask)#调用相应的函数

selctor实现IO多路复用

												

python第10天(下)的更多相关文章

  1. python基础——面向对象进阶下

    python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...

  2. python python中那些双下划线开头的那些函数都是干啥用用的

    1.写在前面 今天遇到了__slots__,,所以我就想了解下python中那些双下划线开头的那些函数都是干啥用用的,翻到了下面这篇博客,看着很全面,我只了解其中的一部分,还不敢乱下定义. 其实如果足 ...

  3. windows 10 64bit下安装Tensorflow+Keras+VS2015+CUDA8.0 GPU加速

    原文地址:http://www.jianshu.com/p/c245d46d43f0 写在前面的话 2016年11月29日,Google Brain 工程师团队宣布在 TensorFlow 0.12 ...

  4. python实现指定目录下批量文件的单词计数:并发版本

    在 文章 <python实现指定目录下批量文件的单词计数:串行版本>中, 总体思路是: A. 一次性获取指定目录下的所有符合条件的文件 -> B. 一次性获取所有文件的所有文件行 - ...

  5. 如何在Windows下开发Python:在cmd下运行Python脚本+如何使用Python Shell(command line模式和GUI模式)+如何使用Python IDE

    http://www.crifan.com/how_to_do_python_development_under_windows_environment/ 本文目的 希望对于,如何在Windows下, ...

  6. python进阶10 MySQL补充 编码、别名、视图、数据库修改

    python进阶10 MySQL补充    编码.别名.视图.数据库修改 一.编码问题 #MySQL级别编码 #修改位置: /etc/mysql/mysql.conf.d/mysqld.cnf def ...

  7. tensor搭建--windows 10 64bit下安装Tensorflow+Keras+VS2015+CUDA8.0 GPU加速

    windows 10 64bit下安装Tensorflow+Keras+VS2015+CUDA8.0 GPU加速 原文见于:http://www.jianshu.com/p/c245d46d43f0 ...

  8. libjingler-0.6.2在windows和ubuntu 10.04下的编译(Google Talk)

    Libjingle版本:0.6.2 所需的资源:         gtest-1.6.0.zip         http://download.csdn.net/detail/cl_gamer/48 ...

  9. Win 10环境下6sV2.1模型编译心得

    最新版本6sV2.1模型是通过FORTRAN95编写的,2017年11月代码编写完成,2018年11月发布在模型官网上.通常我们在使用过程中都是调用模型的.exe可执行文件,而下载下来的是FORTRA ...

  10. Python 入门 之 双下方法

    Python 入门 之 双下方法 1.双下方法 ​ 定义:双下方法是特殊方法,它是解释器提供的 由双下划线加方法名加双下划线 方法名的具有特殊意义的方法,双下方法主要是python源码程序员使用的,我 ...

随机推荐

  1. Linux--前后端分离部署

    项目部署 (vue + nginx + uwsgi + django + mysql + redis) 一 . 前端部署 1. 下载vue代码,解压缩 wget https://files.cnblo ...

  2. 使用jenkins进行前端项目自动部署

    前面的话 后端的nodeJS项目可以使用pm2进行自动部署,由于前端项目打包后是静态资源,不需要进程守护.一般地,前端项目使用jenkins来进行自动部署,包括打包.测试等一系列流程.本文将详细介绍j ...

  3. axios页面无刷新提交from表单

    页面部分大概意思一下 <form method="post" enctype="multipart/form-data"> ... </for ...

  4. codeforces选做

    收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故 ...

  5. LOJ #2731. 「JOISC 2016 Day 1」棋盘游戏(dp)

    题意 JOI 君有一个棋盘,棋盘上有 \(N\) 行 \(3\) 列 的格子.JOI 君有若干棋子,并想用它们来玩一个游戏.初始状态棋盘上至少有一个棋子,也至少有一个空位. 游戏的目标是:在还没有放棋 ...

  6. wireshark分析dhcp过程

    ---恢复内容开始--- DHCP DHCP(Dynamic Host Configuration Protocol)是一个用于主机动态获取IP地址的配置解 析,使用UDP报文传送,端口号为67何68 ...

  7. JavaScript闭包应用的整理

    0 什么是JavaScript闭包? 当函数定义内部的函数被保存到外部时,就会形成闭包.闭包会导致作用域链不释放,造成内存泄漏. 1 获取局部变量 [练习目的] 下面这个练习,是为了通过闭包实现获取定 ...

  8. Cucumber常用关键字

    常用关键字(中英文对应) 对应的测试用例 Feature(功能) test suite (测试用例集) background(背景)   Scenario(场景) test case(测试用例) Sc ...

  9. 关于QQ农场牧场等曾经流行的游戏的一些见解

    大概在上上周,我偶然间打开QQ空间玩了一会QQ农牧场,玩完之后我在想,在那个年代他们为什么那么红? 我觉得可能有以下几点: 1:凭借着QQ海量的用户,可以迅速推广 2:迎合了人们爱占小便宜的心理,不过 ...

  10. Kubernetes之Deployment控制器

    Deployment 简介 deployment 是用来管理无状态应用的,面向的集群的管理,而不是面向的是一个不可变的个体,举例:有一群鸭子,要吃掉一个,只需要再放一个新的鸭仔就好了,不会影响什么,而 ...