前言:

什么是IO?
  • 分为IO设备和IO接口两个部分
  • 如Linux系统,I/O操作可以有多种方式
  • 比如DIO(DirectI/O)
  • AIO(AsynchronousI/O异步I/O)
  • Memory-MappedI/O(内存映设I/O)等...
  • 不同的I/O方式有不同的实现方式和性能,在不同的应用中可以按情况选择不同的I/O方式。

补充昨天HTTP:


from socket import *
# 接收请求
# 查看请求
# 返回客户端段请求内容def handleClient(connfd):request = connfd.recv(4096)# print("***********")# print(request)# print("************")# 按照行切割请求request_lines = request.splitlines()for line in request_lines:print(line.decode())try:f = open('index.html')except IOError:response = "HTTP/1.1 303 Not Found\r\n"response += "\r\n"  # 空行response += '''**************************Sorry, not found the page.**************************'''else:response = "HTTP/1.1 200  OK\r\n"response += '\r\n'response += f.read()finally:# 发送给浏览器
        connfd.send(response.encode())# 创建套接字,调用handleClient完成功能
def main():# 创建tcp套接字sockfd = socket()sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)sockfd.bind(('0.0.0.0', 8000))sockfd.listen()while True:print("Listen the port 8000...")connfd, addr = sockfd.accept()# 处理浏览器发来的请求
        handleClient(connfd)connfd.close()if __name__ == "__main__":main()

S.splitlines  
拆分文件字符串按行分隔

 
 
内存中存在数据交换的操作认为是IO操作(输入输出)
例如:
内存与磁盘数据交换:文件读写、数据库更新
内存和终端数据交换:input、print、sys.stdout、sys.stdin、  sys.stder
内存和网络数据交换:网络连接、recv、send、recvfrom
IO秘集程型序:
程序执行中有大量的IO操作,而比较少的CPU运算操作
 消耗CPU较少,IO运行时间长
cpu(计算)密集形程序:
程序存在大量的CPU运算,IO操作相对较少
CPU消耗大
IO分类:
1.阻塞IO:
程序运行中遇到IO条件没有达成
或传输情况较慢的情况下会出现阻塞状态
阻塞IO是IO最简单的逻辑情形,也是默认状态
阻塞IO是效率很低的IO状态
阻塞情况:
1.因为IO条件没有达成
IO阻塞函数(input、print、recv、recvfrom)
2.处理IO耗时较长形参阻塞
文件读写、网络数据发送过程
2.非阻塞IO:
在程序运行中遇到IO操作不让其产生阻塞
实现手段:
改变IO事件的属性,使其变为非阻塞
通常会和循环一起使用 进行条件的循环监控
 3.IO多路复用
 定义:
通过一个监测,可以同时监控多个IO事件的行为
当那个IO可以执行,让这个IO事件发生
同时监控多个IO事件,当哪个IO事件准备就绪就执行哪个IO事件
此时形成多个IO时间都可以操作的现象,不必逐个等待执行
IO准备就绪:
IO事件即将发生时的临界状态不可逆转
在程序中存在的IO事件中选择要监测的事件
创建监测,将监测的IO事件注册
等待监测的IO事件发生判断是什么事件
处理相应的IO
事件驱动IO
异步IO
...
s.setblocking(False)
功能:
将套接字设置为非阻塞状态
 参数:
默认为阻塞, 设置为False为非阻塞状态
超时检测:
原本阻塞的IO设置一个最长阻塞等待时间
规定时间内如果达到条件正常执行
如果时间到仍未达到条件则结束阻塞
 s.settimeout(sec)
 功能:
设置套接字的超时时间
参数:
时间(
select模块
from select import
select 支持:Windows、Linux、Unix  
poll   支持:Linux、Unix
epoll  支持:Linux、Unix
rs, ws, xs = select(rlist, wlist, xlist[, timeout])
功能:
监控IO事件 ,阻塞等待监控的IO事件发生
参数:
rlist   列表:
表示存放我们需要等待处理的IO
wlist   列表:
表示存放我们想要主动处理的IO
xlist   列表:
表示存放出错希望去处理的IO
timeout: 超时检测
返回值:
rs  列表:
准备就绪的IO
ws  列表:
准备就绪的IO
xs  列表
准备就绪的IO
* 在处理IO时不要形成死循环会让一个客户端单独占有服务端
IO多路复兴形成一种可以同时处理多个IO的效果效率较高

位运算:
按照二进制位进行位运算操作
& 按为与   |  按位或   ^  按位异或
<< 左异    >>右移
11  1011
14  1110
&   1010  有0得0
|    1111  有1得1
^    0101  相同为0不同为1
11 << 2  == 44   右侧补零(乘2乘2次)
14 >> 2  == 3    挤掉右侧的数字(地板除2除2次)
使用:
1.在低层硬件操作寄存器
2.做标志位的过滤
poll方法实现IO多路复用:
1.创建poll对象:
    p = select.poll
 2.注册关注的IO:
 p.register(s, POLLIN | PLLERR)
不关注:
 p.unregister(s)
 事件类别:
          POLLIN  POLLOUT  POLLERR  POLLHUP   POLLPRI
            rlist           wlist          xlist          断开       紧急处理 
3.监控IO:
events = p.poll()
功能:监控关注的IO事件
返回值:
返回发生IO事件
events是一个列表[(fileno, evnet), (), ()....]
每个就绪IO对应一个元组描述符就绪事件
IO地图{s.fileno():s}
   4.处理IO事件
poll方法实现IO多路复用:
from socket import *
from select import *s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(('0.0.0.0',8888))
s.listen(5)#创建poll对象
p = poll()#创建地图
fdmap = {s.fileno():s}#添加关注
p.register(s,POLLIN | POLLERR)while True:#进行IO监控#[(fileno,evnet),...]events = p.poll()for fd,event in events:if fd == s.fileno():#从地图中找到fd对应的对象c,addr = fdmap[fd].accept()print("Connect from",addr)#注册新的IO 维护地图
            p.register(c,POLLIN)fdmap[c.fileno()] = c else:data = fdmap[fd].recv(1024)if not data:p.unregister(fd) #从关注移除
                fdmap[fd].close()del fdmap[fd]  #从地图删除else:print(data.decode())fdmap[fd].send('收到了'.encode())

 
select IO多路复用服务器端:
 
from socket import *
from select import select
# 创建套接字
s = socket()
# 设置端口重用
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 绑定地址
s.bind(('0.0.0.0', 8888))
# 设置队列
s.listen(5)
# 注册监听套接字
rlist = [s]
wlist = []
xlist = [s]while True:print("等待IO发生")rs, ws, xs = select(rlist, wlist, xlist)# 循环遍历rs准备就绪列表for r in rs:# 如果有新的客户端链接请求if r is s:# 链接客户端并返回客户端套接字connfd, addr = r.accept()  # r==s 原套接字print("Connect from", addr)# 将绑定客户端套接字加入监听列表
            rlist.append(connfd)# 表示客户端连接套接字准备就绪else:# 如果是客户端套接字发送数据 则接收data = r.recv(1024)if not data:  # 如果客户端断开链接# 从关注列表移除connfd
                rlist.remove(r)r.close()  # 关闭套接字else:print("Receive:", data.decode())# 讲客户端套接字放入wlist
                wlist.append(r)# wlist列表会直接返回# 循环遍历ws准备就绪列表for w in ws:# 消息回复w.send("这是一条回复消息".encode())# 删除并取消监听已处理消息
        wlist.remove(w)# xs列表:待处理异常for x in xs:if x is s:s.close()

sys.stdin
 
客户端:
 
from socket import *#  创建套接字
sockfd = socket()#  发起连接
sockfd.connect(('127.0.0.1', 8888))while True:#  消息收发msg = input("Msg>>")if not msg:breaksockfd.sendall(msg.encode())data = sockfd.recv(1024)print(data.decode())sockfd.close()

应用 :
select服务端,同时关注客户端连接
客户端发送和终端输入。将客户端发送和终端输入的内容全都写入到一个文件中
# myserver.py
# 应用 :
# select服务端,同时关注客户端连接
# 客户端发送和终端输入。将客户端发送和终端输入的内容全都写入到一个文件中from socket import *
from select import *
from sys import stdinsock = socket()
sock.getsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sock.bind(("127.0.0.1", 6666))
sock.listen(5)
rlist = [sock, stdin]
wlist = []
xlist = []
file = open("selectdemo.txt", "w+b")
while True:rs, ws, xs, = select(rlist, wlist, xlist)for r in rs:if r == sock:connfd, addr = r.accept()print("已连接......")rlist.append(connfd)elif r == stdin:data = stdin.readline()file.write(data.encode())file.flush()else:data = r.recv(4096)if not data:rlist.remove(r)r.close()else:file.write(data + "\n".encode())file.flush()print("已经接收内容并写如select>>>.txt文件内\n 内容:", data.decode())r.send("接收成功!".encode())
file.close()


from socket import *#  创建套接字
sockfd = socket()#  发起连接
sockfd.connect(('127.0.0.1', 6666))while True:#  消息收发msg = input("Msg>>")if not msg:breaksockfd.sendall(msg.encode())data = sockfd.recv(1024)print(data.decode())sockfd.close()

 
 
 

转载于:https://www.cnblogs.com/ParisGabriel/p/9446617.html

Python网络编程(http协议,IO多路复用、select内核监听)相关推荐

  1. python网络编程—TCP协议(一)

    一.TCP协议示意图: listen():监听客户端的连接,客户端有链接,listen马上就有返回. accept():连接之后,会返回客户端的信息(ip地址.端口号),如果没有连接则一直堵塞.连接成 ...

  2. Python网络编程——TCPIP协议

    1.网络编程就是通过网络让不同计算机上运行的程序可以进行通信. 2.软件间的通信分为两种 应用类程序(QQ)和web类程序(百度) 3.客户端:就是常用的程序QQ: 服务端:一致运行着个别人的提供服务 ...

  3. python网络编程—UDP协议

    一.UDP协议特点: UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送.UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之 ...

  4. python网络编程—TCP协议(二)

    一.TCP协议的原理图 每个客户端与服务端通讯是互不干扰的 二.注意点 1.tcp服务器─般情况下都需要绑定,否则客户端找不到这个服务器 2.tcp客户端一般不绑定,因为是主动链接服务器,所以只要确定 ...

  5. python网络编程smtp协议发送电子邮件

    SMTP协议 SMTP 的全称是"Simple Mail Transfer Protocol",即简单邮件传输协议.它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的 ...

  6. Python网络编程——HTTP协议学习笔记

    HTTP协议学习笔记 HTTP协议概述 一.HTTP协议的介绍 HTTP协议的全称是(HyperText Transfer Protocol),翻译过来就是超文本传输协议. 超文本是超级文本的缩写,是 ...

  7. Python网络编程:IO多路复用

    io多路复用:可以监听多个文件描述符(socket对象)(文件句柄),一旦文件句柄出现变化,即可感知. 1 sk1 = socket.socket() 2 sk1.bind(('127.0.0.1', ...

  8. C语言 IO多路复用——select函数

    友链 可以实现并发的效果 gcc 1.c -o 1 -lpthread ctrl+f搜索服务端代码和客户端代码获取代码 IO多路复用,IO多路转接 简介 IO多路复用中的IO并不是指单纯的标准输入和输 ...

  9. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)...

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程并行与并发同步与异步阻塞与非阻塞CPU密集型与IO密集型 线程与进程 进程 前言 ...

  10. python php 全双工,Python网络编程之使用select实现socket全双工异步通信功能

    这篇文章主要介绍了Python网络编程使用select实现socket全双工异步通信功能,在这里分享给大家,有需要的朋友可以参考下 本文实例讲述了Python网络编程使用select实现socket全 ...

最新文章

  1. ID vs Class 老生常谈的选择器问题
  2. X3D.Studio编辑器界面介绍
  3. c语言线性表拷贝,数据结构(C语言版)---线性表顺序存储表示
  4. 【LOJ#2507】[CEOI2011]Matching(KMP,树状数组)
  5. java(17) - 增强for循环、装箱拆箱、可变参数
  6. LeetCode 285. Inorder Successor in BST
  7. oracle约束 1或0,Oracle笔记(十) 约束
  8. 同时安装vs2010和VS2012后IEnumerableModelClientValidationRule编译错误
  9. vs2010 sp1 安装Silverlight5 语言版本不匹配 解决方案
  10. TensorFlow应用实战-18-Policy Gradient算法
  11. windows PAE扩展和AWE编程
  12. SEO自动外链工具推荐:站群推广利器SEO,在线批量发外链让新站快速收录
  13. 微信小程序英语学习平台+后台管理系统
  14. 多智时代,人工智能发展历史的时间表
  15. c lua语言教程,Lua教程(十九):C调用Lua
  16. 锐捷(三)清除交换机的虚拟化(VSU)配置
  17. [Vuforia]二.3D物体识别
  18. javaweb-jsp编程例题
  19. @Value,@ConfigurationProperties,@EnableConfigurationProperties,@PropertySource,@PropertySources
  20. 透彻理解半监督学习的重要思想及概率视角

热门文章

  1. UCIPC2012-Red/Blue Spanning Tree解题报告
  2. ICLR'22 | 微软亚洲研究院深度学习领域最新研究成果一览
  3. 【实践】Pytorch nn.Transformer的mask理解
  4. 【综述笔记】Graph Neural Networks in Recommender Systems
  5. 什么时候以及为什么基于树的模型可以超过神经网络模型?
  6. 【ACL2020】最新效果显著的关系抽取框架了解一下?
  7. 推荐 | 掌握这些套路,你也能解决 90% 的 NLP 问题
  8. 【每日算法Day 100】字节跳动 AI Lab 面试编程题(三道)
  9. 每日算法系列【LeetCode 128】最长连续序列
  10. matplotlib—matplotlib绘图中出现□的解决办法