Socket Server模块
SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进 程” 专门负责处理当前客户端的所有请求。
socket server 和 select & epoll 还是不太一样他的本质是:客户端第一次链接的时候,只要一进来,我服务端有个while循环为你创建一个
线程和进程,客户端就和服务端直接创建通信,以后传送数据什么的就不会通过server端了,直接他俩通过线程或者进程通信就可以了!
如果在多进程的时候,client1和client2他们同时传输10G的文件都是互相不影响!
如果在多线程的时候,python中的多线程,在同一时间只有一个线程在工作,他底层会自动进行上下文切换,client1传一点,client2传一点。
知识回顾:
python中的多线程,有一个GIL在同一时间只有一个线程在工作,他底层会自动进行上下文切换.
这样会导致python的多线程效率会很低,也就是人们经常说的python多线程问题
如下图:
第一次连接后,数据通讯就通过线程或进程进行数据交换(红色箭头)
ThreadingTCPServer
ThreadingTCPServer实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互。
1、ThreadingTCPServer基础
使用ThreadingTCPServer:
- 创建一个继承自 SocketServer.BaseRequestHandler 的类
- 类中必须定义一个名称为 handle 的方法
- 启动ThreadingTCPServer
#!/usr/bin/env python # -*- coding:utf-8 -*- import SocketServer class MyServer(SocketServer.BaseRequestHandler): def handle(self): #定义handle方法 # print self.request,self.client_address,self.server conn = self.request #如果连接请求过来,获取client端对象 conn.sendall('欢迎致电 10086,请输入1xxx,0转人工服务.') #发送一个信息 Flag = True #并把Flag设置为True while Flag:当Flag为True的时候执行 data = conn.recv(1024) #接收client端数据 if data == 'exit': #判断如果data == 'exit' 退出 Flag = False #并把Flag设置为Flase elif data == '0': #如果为 == ‘0’ conn.sendall('通过可能会被录音.balabala一大推') #发送数据 else:#上面的都没匹配上,发送请重新输入 conn.sendall('请重新输入.') if __name__ == '__main__': server = SocketServer.ThreadingTCPServer(('127.0.0.1',8009),MyServer) #实例化对象,设置启动的IP/PORT并把自己定义的类写上作为SocketServer.ThreadingTCPServer的构造函数 server.serve_forever() #调用对象中的启动方法