BaseServer 和 BaseRequestHandler
Python为网络编程提高了更高级的封装。SocketServer.py 提供了不少网络服务的类。它们的设计很优雅。Python把网络服务抽象成两个主要的类,一个是Server类,用于处理连接相关的网络操作,另外一个则是RequestHandler类,用于处理数据相关的操作。并且提供两个MixIn 类,用于扩展 Server,实现多进程或多线程。在构建网络服务的时候,Server 和 RequestHandler 并不是分开的,RequestHandler的实例对象在Server 内配合 Server工作。
改模块的主要几个Server
关系如下:
+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+
BaseServer 分析
BaseServer 通过__init__
初始化,对外提供serve_forever和 handler_request方法。
init 初始化
def __init__(self, server_address, RequestHandlerClass):
"""Constructor. May be extended, do not override."""
self.server_address = server_address
self.RequestHandlerClass = RequestHandlerClass
self.__is_shut_down = threading.Event()
self.__shutdown_request = False
__init__
源码很简单。主要作用是创建server对象,并初始化server地址和处理请求的class。熟悉socket编程应该很清楚,server_address是一个包含主机和端口的元组。
serve_forever
创建了server对象之后,就需要使用server对象开启一个无限循环,下面来分析serve_forever的源码。
def serve_forever(self, poll_interval=0.5):
self.__is_shut_down.clear()
try:
while not self.__shutdown_request:
r, w, e = _eintr_retry(select.select, [self], [], [],
poll_interval)
if self in r:
self._handle_request_noblock()
finally:
self.__shutdown_request = False
self.__is_shut_down.set()
serve_forever接受一个参数poll_interval,用于表示select轮询的时间。然后进入一个无限循环,调用select方式进行网络IO的监听。
如果select函数返回,表示有IO连接或数据,那么将会调用_handle_request_noblock方法。
_handle_request_noblock
def _handle_request_noblock(self):
try:
request, client_address = self.get_request()
except socket.error:
return
if self.verify_request(request, client_address):
try:
self.process_request(request, client_address)
except:
self.handle_error(request, client_address)
self.shutdown_request(request)
_handle_request_noblock方法即开始处理一个请求,并且是非阻塞。该方法通过get_request方法获取连接,具体的实现在其子类。一旦得到了连接,调用verify_request方法验证请求。验证通过,即调用process_request处理请求。如果中途出现错误,则调用handle_error处理错误,以及shutdown_request结束连接。
verify_request
def verify_request(self, request, client_address):
return True
该方法对request进行验证,通常会被子类重写。简单的返回True即可,然后进入process_request方法处理请求。
process_request
def process_request(self, request, client_address):
self.finish_request(request, client_address)
self.shutdown_request(request)
process_request方法是mixin的入口,MixIn子类通过重写该方法,进行多线程或多进程的配置。调用finish_request完成请求的处理,同时调用shutdown_request结束请求。
finish_request
def finish_request(self, request, client_address):
self.RequestHandlerClass(request, client_address, self)
finish_request方法将会处理完毕请求。创建requestHandler对象,并通过requestHandler做具体的处理。
BaseRequestHandler 分析
所有requestHandler都继承BaseRequestHandler基类。
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle()
finally:
self.finish()
该类会处理每一个请求。初始化对象的时候,设置请求request对象。然后调用setup方法,子类会重写该方法,用于处理socket连接。接下来的将是handler和finish方法。所有对请求的处理,都可以重写handler方法。
至此,整个Python提供的Server方式即介绍完毕。总结一下,构建一个网络服务,需要一个BaseServer用于处理网络IO,同时在内部创建requestHandler对象,对所有具体的请求做处理。
BaseServer - BaseRequestHandler
__init__(server_address, RequestHandlerClass):
BaseServer.server_address
BaseServer.RequestHandlerClass
serve_forever():
select()
BaseServer._handle_request_noblock()
BaseServer.get_request() -> request, client_addres
BaseServer.verify_request()
BaseServer.process_request()
BaseServer.process_request()
BaseServer.finish_request()
BaseServer.RequestHandlerClass()
BaseRequestHandler.__init__(request)
BaseRequestHandler.request
BaseRequestHandler.client_address = client_address
BaseRequestHandler.setup()
BaseRequestHandler.handle()
BaseServer.shutdown_request()
BaseServer.close_request()
BaseServer.shutdown_request()
BaseServer.close_request()