socketserver模块使用方法
一、socketserver模块介绍
Python提供了两个基本的socket模块。一个是socket,它提供了标准的BSD Socket API; 另一个是socketserver,它提供了服务器中心类,可以简化网络服务器的开发
socketserver
socketserver内部使用IO多路复用以及“多线程”和“多进程”,从而实现并发处理多个客户端请求的socket服务端。 即,每个客服端请求连接到服务器时,socket服务端都会在服务器上创建一个“线程”或“进程”专门负责处理当前客户端的所有请求。
二、socketserver中的ThreadingTCPServer类
ThreadingTCPServer实现的socket服务器内部会为每个client创建一个“线程”,该线程用来和客户端就行交互 ThreadingTCPServer源码内容:
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass #可以看到ThreadTCPServer类本身并没有方法,而是继承了(ThreadingMinIn, TCPServer) 这两个类。 而TCPServer则是继承了BaseServer类。
三、ThreadingTCPServer的使用方法
1、创建一个继承socketserver.BaseRequestHandler的类
2、类中必须重写一个名为handler的方法
3、实例化一个服务器类,传入服务器的地址和请求处理程序类
4、调用serve_forever()事件循环监听
1 #!/usr/bin/env python3 2 import socketserver 3 4 class Handler(socketserver.BaseRequestHandler): # 必须继承BaseRequestHandler 5 def handle(self): # 必须有handle方法 6 print('New connection:',self.client_address) 7 while True: 8 data = self.request.recv(1024) 9 if not data:break 10 print('Client data:',data.decode()) 11 self.request.send(data) 12 13 if __name__ == '__main__': 14 server = socketserver.ThreadingTCPServer(('127.0.0.1',8009),Handler) # 实例化对象,实现多线程的socket 15 server.serve_forever() # 事件监听,并调用handler方法
四、ThreadingTCPServer执行过程
1、启动服务端程序
2、执行TCPServer.__init__方法,创建服务端socket对象并绑定IP和端口(根据类的继承关系,即查找顺序找到TCPServer.__init__())
3、执行BaseServer.__init__方法,将自定义的继承自socketserver.BaseRequestHandler的类MyRequestHandler赋值给self.RequestHandlerClass class TCPServer(BaseServer): #(继承了BaseServeer类)
1 class TCPServer(BaseServer): #(继承了BaseServeer类) 2 def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): 3 """Constructor. May be extended, do not override.""" 4 BaseServer.__init__(self, server_address, RequestHandlerClass) #(重写了BaseServer的__init__方法) 5 self.socket = socket.socket(self.address_family, 6 self.socket_type) 7 if bind_and_activate: 8 try: 9 self.server_bind() 10 self.server_activate() 11 except: 12 self.server_close() 13 raise 14 15 class BaseServer: 16 def __init__(self, server_address, RequestHandlerClass): #(接收了两个传进来的参数) 17 """Constructor. May be extended, do not override.""" 18 self.server_address = server_address 19 self.RequestHandlerClass = RequestHandlerClass #(赋值给了self.RequestHandlerClass) 20 self.__is_shut_down = threading.Event() 21 self.__shutdown_request = False
4、通过实例化的对象,执行serve_forever方法,该方法首先查找到BaseServer下的方法,通过调用selector模块,注册事件监听对象,并执行_handle_request_noblock方法 找到此方法,并调用该方法下的process_request方法,在此调用到finish_request方法,通过finish_request方法,执行了RequestHandlerClass方法,执行此方法就相当于调用 了我们重写的Handler类。
1 class BaseServer: 2 def serve_forever(self, poll_interval=0.5): 3 try: 4 with _ServerSelector() as selector: 5 selector.register(self, selectors.EVENT_READ) 6 7 while not self.__shutdown_request: 8 ready = selector.select(poll_interval) 9 if ready: 10 self._handle_request_noblock() 11 12 self.service_actions() 13 def _handle_request_noblock(self): 14 try: 15 request, client_address = self.get_request() 16 except OSError: 17 return 18 if self.verify_request(request, client_address): 19 try: 20 self.process_request(request, client_address) 21 except Exception: 22 self.handle_error(request, client_address) 23 self.shutdown_request(request) 24 except: 25 self.shutdown_request(request) 26 raise 27 else: 28 self.shutdown_request(request) 29 def process_request(self, request, client_address): 30 self.finish_request(request, client_address) 31 self.shutdown_request(request) 32 def finish_request(self, request, client_address): 33 self.RequestHandlerClass(request, client_address, self)
5、通过Handler类实例化对象,调用继承的BaseRequestHandler类中的__init__方法,并执行了handler方法。 从而运行了我们重写Handler类中的handler方法。
class BaseRequestHandler: def __init__(self, request, client_address, server): self.request = request self.client_address = client_address self.server = server self.setup() try: self.handle() #调用handler() finally: self.finish()