python16_day09【Select多路复用】
一、select多路复用
句柄列表11, 句柄列表22, 句柄列表33 = select.select(句柄序列1, 句柄序列2, 句柄序列3, 超时时间) 参数: 可接受四个参数(前三个必须)
返回值:三个列表 select方法用来监视文件句柄,如果句柄发生变化,则获取该句柄。
1、当 参数1 序列中的句柄发生可读时(accetp和read),则获取发生变化的句柄并添加到 返回值1 序列中
2、当 参数2 序列中含有句柄时,则将该序列中所有的句柄添加到 返回值2 序列中
3、当 参数3 序列中的句柄发生错误时,则将该发生错误的句柄添加到 返回值3 序列中
4、当 超时时间 未设置,则select会一直阻塞,直到监听的句柄发生变化
当 超时时间 = 1时,那么如果监听的句柄均无任何变化,则select会阻塞 1 秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。
import select
import socket sk1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk1.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sk1.bind(('127.0.0.1', 8001),)
sk1.listen(5) sk2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sk2.bind(('127.0.0.1', 8002),)
sk2.listen(5) inputs = [sk1, sk2]
w_inputs = []
while True:
# IO多路复用,同时监听多个SOCKET对象.
r, w, e = select.select(inputs, w_inputs, inputs, 0.05) # for obj in r:
print("obj::::", obj)
print("sk1::::", sk1)
if obj in [sk1, sk2]:
# 新连接
print("新连接....", obj)
conn, addr = obj.accept()
inputs.append(conn)
else:
# 有连接用户发送消息来了...
print("有用户发数据了", obj)
try:
data = obj.recv(1024)
except Exception as e:
data = ""
if data:
w_inputs.append(obj)
# obj.sendall(data)
else:
obj.close()
inputs.remove(obj)
w_inputs.remove(obj) for obj in w_inputs:
obj.sendall(b'ok')
w_inputs.remove(obj)
利用select实现伪同时处理多个Socket客户端请求:服务端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 8001))
while True:
v = input(">>>>")
if v == 'exit':
break
client.sendall(bytes(v, encoding='utf8'))
ret = client.recv(1024)
print("server respone:", ret)
client.close()
利用select实现伪同时处理多个Socket客户端请求:客户端
二、socketserver模块
SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。
即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进程” 专门负责处理当前客户端的所有请求。

1.ThreadingTCPServer
ThreadingTCPServer实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互。
使用ThreadingTCPServer:
- 创建一个继承自 SocketServer.BaseRequestHandler 的类
- 类中必须定义一个名称为 handle 的方法
- 启动ThreadingTCPServer
import SocketServer
class MyServer(SocketServer.BaseRequestHandler):
def handle(self):
# print self.request,self.client_address,self.server
conn = self.request
conn.sendall('欢迎致电 10086,请输入1xxx,0转人工服务.')
Flag = True
while Flag:
data = conn.recv(1024)
if data == 'exit':
Flag = False
elif data == '':
conn.sendall('通过可能会被录音.balabala一大推')
else:
conn.sendall('请重新输入.')
if __name__ == '__main__':
server = SocketServer.ThreadingTCPServer(('127.0.0.1',8009),MyServer)
server.serve_forever()
secketserver服务端
import socket
ip_port = ('127.0.0.1',8009)
sk = socket.socket()
sk.connect(ip_port)
sk.settimeout(5)
while True:
data = sk.recv(1024)
print 'receive:',data
inp = raw_input('please input:')
sk.sendall(inp)
if inp == 'exit':
break
sk.close()
socketserver客户端
2.源码剖析

内部调用流程为:
- 启动服务端程序
- 执行 TCPServer.__init__ 方法,创建服务端Socket对象并绑定 IP 和 端口
- 执行 BaseServer.__init__ 方法,将自定义的继承自SocketServer.BaseRequestHandler 的类 MyRequestHandle赋值给 self.RequestHandlerClass
- 执行 BaseServer.server_forever 方法,While 循环一直监听是否有客户端请求到达 ...
- 当客户端连接到达服务器
- 执行 ThreadingMixIn.process_request 方法,创建一个 “线程” 用来处理请求
- 执行 ThreadingMixIn.process_request_thread 方法
- 执行 BaseServer.finish_request 方法,执行 self.RequestHandlerClass() 即:执行 自定义 MyRequestHandler 的构造方法(自动调用基类BaseRequestHandler的构造方法,在该构造方法中又会调用 MyRequestHandler的handle方法)
import socket
import threading
import select def process(request, client_address):
print request,client_address
conn = request
conn.sendall('欢迎致电 10086,请输入1xxx,0转人工服务.')
flag = True
while flag:
data = conn.recv(1024)
if data == 'exit':
flag = False
elif data == '':
conn.sendall('通过可能会被录音.balabala一大推')
else:
conn.sendall('请重新输入.') sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.bind(('127.0.0.1',8002))
sk.listen(5) while True:
r, w, e = select.select([sk,],[],[],1)
print 'looping'
if sk in r:
print 'get request'
request, client_address = sk.accept()
t = threading.Thread(target=process, args=(request, client_address))
t.daemon = False
t.start() sk.close()
精简版sockserver
如精简代码可以看出,SocketServer的ThreadingTCPServer之所以可以同时处理请求得益于 select 和 Threading 两个东西,其实本质上就是在服务器端为每一个客户端创建一个线程,当前线程用来处理对应客户端的请求,所以,可以支持同时n个客户端链接(长连接)。
python16_day09【Select多路复用】的更多相关文章
- Golang的select多路复用以及channel使用实践
看到有个例子实现了一个类似于核弹发射装置,在发射之前还是需要随时能输入终止发射. 这里就可以用到cahnnel 配合select 实现多路复用. select的写法用法有点像switch.但是和swi ...
- 转:linux select 多路复用机制
源地址:http://blog.csdn.net/turkeyzhou/article/details/8609360 2013-02-25 14:18 442人阅读 评论(1) 收藏 举报 目录 ...
- Go语言协程并发---select多路复用应用
package main import ( "fmt" "time" ) /* ·循环从一写两读三条管道中随机选择一条能走的路 ·等所有路都走不通了就退出循环 ...
- python tcp select 多路复用
1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 # 文件名:tcpserver.py 4 5 import socket 6 import time 7 ...
- linux select 与 阻塞( blocking ) 及非阻塞 (non blocking)实现io多路复用的示例
除了自己实现之外,还有个c语言写的基于事件的开源网络库:libevent http://www.cnblogs.com/Anker/p/3265058.html 最简单的select示例: #incl ...
- 多路复用(select、epoll)实现tcp服务
-------------------------------多路复用的服务器(select)------------------------------- 网络通信被Unix系统抽象为文件的读写,通 ...
- linux select 与 阻塞( blocking ) 及非阻塞 (non blocking)实现io多路复用的示例【转】
转自:https://www.cnblogs.com/welhzh/p/4950341.html 除了自己实现之外,还有个c语言写的基于事件的开源网络库:libevent http://www.cnb ...
- python学习之-- IO多路复用 select模块
python I/O多路复用包括3个模块,上一篇已经说过概念,这里我使用的是select模块实现一个ftp并发 服务器端核心代码: import socket,select import queue, ...
- 各I/O模型 对应Web服务应用模型(select,poll,epoll,kevent,"/dev/poll")
一.利用select多路复用I/O的Web服务应用模型 /* 可读.可写.异常三种文件描述符集的申明和初始化.*/ fd_set readfds, writefds, exceptionfds; F ...
随机推荐
- [转]所有编程皆为 Web 编程
Web编程还远远没有达到完美的境地.其实,还有点乱!没错,随便会写点代码的人就能三下两下地搞出一个糟糕的Web应用:也确实,99%的Web 应用都似狗屎一堆.但是,这也意味着,相当“聪明”的程序员们正 ...
- hdu6070 Dirt Ratio 二分+线段树
/** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...
- eclipse JavaEE版"javax.servlet.http.HttpServlet" was not found on the Java Build Path问题的解决办法
使用eclipse JavaEE 版,新建 Dynamic Web Project 项目.在项目里添加 JSP 文件,会在文件头部出现错误提示.提示语句为:The superclass "j ...
- python笔记2-数据类型:元组、字典常用操作
元组 Python的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. tp=(1,2,3,'a','b' ...
- mysql DBA 指南
Mysql目录 数据库介绍.常见分类 Mysql入门 Mysql安装配置 Mysql多实例安装配置 Mysql常用基本命令 Mysql权限体系 Mysql数据库备份和恢复 Mysql日志 Mysql逻 ...
- Json.net操作json
string str="{\"size\":15,\"query\":{\"match\":{\"data.query. ...
- 安装tomcat出现failed to install tomcat6 service错误及解决方法(转载)
安装安装版tomcat会出现failed to install tomcat6 service ,check your setting and permissio的概率是非常低的,但是最近楼主就老出现 ...
- java io类图(转)
转载:http://blog.csdn.net/fenglian521/article/details/1324010 Java IO 的类图 拿出来方便大家.Java IO表面上看起来比较乱,有了类 ...
- Castle 整合.NET Remoting
今天研究了一下Castle的Remoting Facility.记录如下: 微软以前使用COM/DCOM的技术来处理分布式系统架构,通过Client端的Proxy代理程序来呼叫远程Server机器上的 ...
- crash处理core文件
(一时心血来潮总结的,供大家参考,时间仓促,不足之处勿拍砖,欢迎讨论~)Crash工具用于解析Vmcore文件,Vmcore文件为通过kdump等手段收集的操作系统core dump信息,在不采用压缩 ...