1、SocketServer:
socket编程过于底层,编程虽然有套路,但是想要写出健壮的代码还是比较困难的,所以很多语言都对socket底层
API进行封装,Python的封装就是——socketserver模块。它是网络服务编程框架,便于企业级快速开发
2、类的继承关系:
+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+
SocketServer简化了网络服务器的编写。
它有4个同步类:
TCPServer,UDPServer,UnixStreamServer,UnixDatagramServer。
2个Mixin类:
ForkingMixIn 和 ThreadingMixIn 类,用来支持异步。
class ForkingUDPServer(ForkingMixIn, UDPServer): pass
class ForkingTCPServer(ForkingMixIn, TCPServer): pass
class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
fork是创建多进程,thread是创建多线程
3、编程接口:
socketserver.BaseServer(server_address, RequestHandlerClass)
需要提供服务器绑定的地址信息,和用于处理请求的RequestHandlerClass类。
RequestHandlerClass类必须是BaseRequestHandler类的子类,在BaseServer中代码如下:
1 # BaseServer代码 ----》 2 class BaseServer: 3 def __init__(self, server_address, RequestHandlerClass): 4 """Constructor. May be extended, do not override.""" 5 self.server_address = server_address 6 self.RequestHandlerClass = RequestHandlerClass 7 self.__is_shut_down = threading.Event() 8 self.__shutdown_request = False 9 def finish_request(self, request, client_address): # 处理请求的方法 10 """Finish one request by instantiating RequestHandlerClass.""" 11 self.RequestHandlerClass(request, client_address, self) # RequestHandlerClass构造
BaseRequestHandler类
它是和用户连接的用户请求处理类的基类,定义为BaseRequestHandler(request, client_address, server)
服务端Server实例接收用户请求后,最后会实例化这个类。
它被初始化时,送入3个构造参数:request, client_address, server自身
以后就可以在BaseRequestHandler类的实例上使用以下属性:
self.request是和客户端的连接的socket对象
self.server是TCPServer实例本身
self.client_address是客户端地址‘
这个类在初始化的时候,它会依次调用3个方法。子类可以覆盖这些方法。
1 # BaseRequestHandler要子类覆盖的方法 2 class BaseRequestHandler: 3 def __init__(self, request, client_address, server): 4 self.request = request 5 self.client_address = client_address 6 self.server = server 7 self.setup() 8 try: 9 self.handle() 10 finally: 11 self.finish() 12 def setup(self): # 每一个连接初始化 13 pass 14 def handle(self): # 每一次请求处理 15 pass 16 def finish(self): # 每一个连接清理 17 pass
测试:
1 import threading 2 import socketserver 3 4 class MyHandler(socketserver.BaseRequestHandler): 5 def handle(self): 6 # super().handle() # 可以不调用,父类handle什么都没有做,一般习惯性的调用一下父类的 7 print('-'*30) 8 print(self.__dict__) 9 print(self.server) # 服务 10 print(self.request) # 服务端负责客户端连接请求的socket对象 11 print(self.client_address) # 客户端地址 12 print(self.__dict__) 13 print(self.server.__dict__) # 能看到负责accept的socket 14 15 print(threading.enumerate()) 16 print(threading.current_thread()) 17 print('-'*30) 18 19 addr = ('127.0.0.1', 9999) 20 server = socketserver.ThreadingTCPServer(addr, MyHandler) # 生成一个多线程的server 21 print(server.__class__.__name__) 22 23 24 server.serve_forever() # 永久开启