设为首页 加入收藏

TOP

python之socket开发(三)
2017-09-30 17:10:29 】 浏览:446
Tags:python socket 开发
另一个本质的改进在于epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。 View Code

 Python中有一个select模块,其中提供了:select、poll、epoll三个方法,分别调用系统的 select,poll,epoll 从而实现IO多路复用。

1 Windows Python:
2     提供: select
3 Mac Python:
4     提供: select
5 Linux Python:
6     提供: select、poll、epoll
7 注意:网络操作、文件操作、终端操作等均属于IO操作,对于windows只支持Socket操作,其他系统支持其他IO操作,但是无法检测 普通文件操作 自动上次读取是否已经变化。
View Code

对于select方法特点

 1 句柄列表11, 句柄列表22, 句柄列表33 = select.select(句柄序列1, 句柄序列2, 句柄序列3, 超时时间)
 2  
 3 参数: 可接受四个参数(前三个必须)
 4 返回值:三个列表
 5  
 6 select方法用来监视文件句柄,如果句柄发生变化,则获取该句柄。
 7 1、当 参数1 序列中的句柄发生可读时(accetp和read),则获取发生变化的句柄并添加到 返回值1 序列中
 8 2、当 参数2 序列中含有句柄时,则将该序列中所有的句柄添加到 返回值2 序列中
 9 3、当 参数3 序列中的句柄发生错误时,则将该发生错误的句柄添加到 返回值3 序列中
10 4、当 超时时间 未设置,则select会一直阻塞,直到监听的句柄发生变化
11    当 超时时间 = 1时,那么如果监听的句柄均无任何变化,则select会阻塞 1 秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。
View Code

利用select监听终端操作实例

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import select
 5 import threading
 6 import sys
 7 
 8 while True:
 9     readable, writeable, error = select.select([sys.stdin,],[],[],1)
10     if sys.stdin in readable:
11         print 'select get stdin',sys.stdin.readline()
View Code

利用select实现伪同时处理多个Socket客户端请求

 1 import socket
 2 import select
 3 
 4 sk1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 5 sk1.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 6 sk1.bind(('127.0.0.1',8002))
 7 sk1.listen(5)
 8 sk1.setblocking(0)
 9 
10 inputs = [sk1,]
11 
12 while True:
13     readable_list, writeable_list, error_list = select.select(inputs, [], inputs, 1)
14     for r in readable_list:
15         # 当客户端第一次连接服务端时
16         if sk1 == r:
17             print 'accept'
18             request, address = r.accept()
19             request.setblocking(0)
20             inputs.append(request)
21         # 当客户端连接上服务端之后,再次发送数据时
22         else:
23             received = r.recv(1024)
24             # 当正常接收客户端发送的数据时
25             if received:
26                 print 'received data:', received
27             # 当客户端关闭程序时
28             else:
29                 inputs.remove(r)
30 
31 sk1.close()
server
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 import socket
 4 
 5 ip_port = ('127.0.0.1',8002)
 6 sk = socket.socket()
 7 sk.connect(ip_port)
 8 
 9 while True:
10     inp = raw_input('please input:')
11     sk.sendall(inp)
12 sk.close()
client

以上代码实质上是通过select对数据循环排队处理,并不是真正意义上的并发处理,SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进程” 专门负责处理当前客户端的所有请求。

 

ThreadingTCPServer

ThreadingTCPServer实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互。

1、ThreadingTCPServer基础

使用ThreadingTCPServer:

  • 创建一个继承自 SocketServer.BaseRequestHandler 的类
  • 类中必须定义一个名称为 handle 的方法
  • 启动ThreadingTCPServer

代码实现实例如下

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 import SocketServer
 4 
 5 class MyServer(SocketServer.BaseRequestHandler):
 6 
 7     def handle(self):
 8         # print self.request,self.client_address,self.server
 9         conn = self.request
10         conn.sendall('欢迎致电 10086,请输入1xxx,0转人工服务.')
11         Flag = True
12         while Flag:
13             data = conn.recv(1024)
14             if data == 'exit':
15                 Flag = False
16             elif data == '0':
17                 conn.sendall('通过可能会被录音.balabala一大推')
18             else:
19                 conn.sendall('请重新输入.')
20 
21 
22 if __name__ == '__main__':
23     server = SocketServer.Thre
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Python初学者(二) 下一篇由python为入口回顾C++的lambda

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目