Python网络编程:IO多路复用
2017-07-24 23:47
260 查看
io多路复用:可以监听多个文件描述符(socket对象)(文件句柄),一旦文件句柄出现变化,即可感知。
IO多路复用有一种机制,可以接受多个文件描述符,一旦有谁变化了,就处理。
select底层实现原理:
系统内部c语言进行for循环检测,当文件句柄发送变化的时候告诉我们。性能较低,并且只支持最多1024个文件描述符。
所以后来就有了poll,对于文件描述符个数没限制了,但底层也是用for循环实现的。
之后又出现了epoll,底层就不用for循环了,而是用异步实现的,把句柄都放进去,谁有变化了谁主动告诉epoll,而不是for循环一遍遍监测。所以epoll的性能是最高的。
Nginx的内部就是socket结合epoll来监听用户请求的。
for sk in e_list: #e_list是发生错误的文件描述符列表
inputs.remove(sk)
IO多路复用处理多用户请求上面的难点在于要理解r_list其实并不等于inputs.
inputs里面两类数据,一类是服务端的socket sk1,另一类是客户端的socket(只要有人来连接就apend一个socket对象)
而r_list里面存的是发生变化的对象,多个用户来连sk1,r_list里就是sk1,而有用户发消息,那r_list里就变为发消息的socket对象其。
1 sk1 = socket.socket() 2 sk1.bind(('127.0.0.1',8001)) 3 sk1.listen() 4 5 # sk2 = socket.socket() 6 # sk2.bind(('127.0.0.1',8002)) 7 # sk2.listen() 8 while True: 9 conn,address = sk.accept()#阻塞等待客户端连接、连接、客户端地址信息 10 print(conn,address) 11 conn.sendall(bytes('北京欢迎你',encoding='utf-8')) 12 while True: 13 ret_bytes = conn.recv(1024) 14 ret_str = str(ret_bytes,encoding='utf-8') 15 if ret_str == 'q': 16 break 17 conn.sendall(bytes(ret_str+'好',encoding='utf-8')) 18 print(address,conn) 19sk1\sk2就叫作文件描述符、文件句柄。上面的程序只能执行sk1。
IO多路复用有一种机制,可以接受多个文件描述符,一旦有谁变化了,就处理。
1 import socket 2 sk1 = socket.socket() 3 sk1.bind(('127.0.0.1',8001)) 4 sk1.listen() 5 6 sk2 = socket.socket() 7 sk2.bind(('127.0.0.1',8002)) 8 sk2.listen() 9 10 sk3 = socket.socket() 11 sk3.bind(('127.0.0.1',8002)) 12 sk3.listen() 13 14 inputs = [sk1,sk2] 15 #本例是用select伪装成多处理用户连接请求,比socket的好处在于不用等待? 难点在于inputs里两类socket,客户端socket和服务端socket? 16 import select 17 while True: 18 #[sk1,sk2,],select内部自动监听sk1,sk2,sk3三个对象,一旦某个句柄发生变化,就会将其放到r_list里。第一次发生变化是sk.accept(),即有人来连sk1.则r_list = [sk1] 19 r_list,w_list,e_list = select.select(inputs,outputs,inputs,1)#等一秒看是否有人来连接,没有的话执行下一次循环。最多等待的时间。 20 print('正在监听的socket对象%d' % len(inputs)) 21 print(r_list) 22 for sk1_or_conn in r_list: 23IO多路复用是操作系统底层提供的功能,我们只是用Python去调用它,分三种方式,select,poll,epoll。windows只支持select.
select底层实现原理:
系统内部c语言进行for循环检测,当文件句柄发送变化的时候告诉我们。性能较低,并且只支持最多1024个文件描述符。
所以后来就有了poll,对于文件描述符个数没限制了,但底层也是用for循环实现的。
之后又出现了epoll,底层就不用for循环了,而是用异步实现的,把句柄都放进去,谁有变化了谁主动告诉epoll,而不是for循环一遍遍监测。所以epoll的性能是最高的。
Nginx的内部就是socket结合epoll来监听用户请求的。
for sk in e_list: #e_list是发生错误的文件描述符列表
inputs.remove(sk)
1 import socket 2 sk1 = socket.socket() 3 sk1.bind(('127.0.0.1',8001)) 4 sk1.listen() 5 6 # sk2 = socket.socket() 7 # sk2.bind(('127.0.0.1',8002)) 8 # sk2.listen() 9 # 10 # sk3 = socket.socket() 11 # sk3.bind(('127.0.0.1',8003)) 12 # sk3.listen() 13 inputs = [sk1] 14 outputs = [] 15 #本例是用select伪装成多处理用户连接请求,比socket的好处在于不用等待? 难点在于inputs里两类socket,客户端socket和服务端socket。 16 import select 17 while True: 18 #[sk1,sk2,],select内部自动监听sk1,sk2,sk3三个对象,一旦某个句柄发生变化 19 r_list,w_list,e_list = select.select(inputs,outputs,inputs,1) 20 print('正在监听的socket对象%d' % len(inputs)) 21 print(r_list) 22 for sk1_or_conn in r_list: 23 #每一个连接对象 24 if sk1_or_conn == sk1: 25 #表示有新用户来连接 26 conn, address = sk1_or_conn.accept() 27 inputs.append(conn) 28 else: 29 #有老用户发消息了 30 try: 31 data_bytes = sk1_or_conn.recv(1024) 32 except Exception as ex: 33 #如果用户中断连接 34 inputs.remove(sk1_or_conn) 35 else: 36 #用户正常发消息 37 # data_str = str(data_bytes,encoding='utf-8') 38 # sk1_or_conn.sendall(bytes(data_str+'好',encoding = 'utf-8')) 39 outputs.append(sk1_or_conn) 40 #w_list仅仅存谁给我发过消息,如果想读写分离就会用到这个参数 41 for conn in w_list: 42 conn.sendall(bytes('hello',encoding='utf-8')) 43 outputs.remove(conn) 44
IO多路复用处理多用户请求上面的难点在于要理解r_list其实并不等于inputs.
inputs里面两类数据,一类是服务端的socket sk1,另一类是客户端的socket(只要有人来连接就apend一个socket对象)
而r_list里面存的是发生变化的对象,多个用户来连sk1,r_list里就是sk1,而有用户发消息,那r_list里就变为发消息的socket对象其。
socketserver:
select/epoll + socket +多线程实现并发操作。
select/epoll + socket +多线程实现并发操作。
相关文章推荐
- Python基础学习(5)网络编程socket、文件上传、粘包问题、socketserver、IO多路复用、线程与进程、进程池、线程池、上下文管理、协程
- [python&php 网络编程]格式化IPv4地址
- Python3网络编程3--http报文结构
- Python tensorflow实战3.神经网络 - 理解到底什么是神经网络,编程原理
- Python 网络编程操作TCP/UDP 初探(一)
- Python 网络爬虫 007 (编程) 通过网站地图爬取目标站点的所有网页
- python网络编程
- python 网络编程学习: 1 初识 SOCKET
- python网络编程--socket
- Python视频教程(入门语法、游戏开发、网络编程)
- Python网络编程之线程与进程
- Python 网络编程
- Python网络编程:E-mail服务(二)传统E-mail格式
- python网络编程之UDP通信实例(含服务器端、客户端、UDP广播例子)
- python读取串口、网络编程、文本处理与文件操作
- Python:网络编程
- python----文件、数据库、网络编程
- Day8 - Python网络编程 Socket编程
- python 网络编程基础
- python网络编程服务器与客户端