标签:http io ar 使用 sp for div on 2014
SocketServer这个模块中定义的类比较多,但是设计比较清晰,我们以TCPServer为主线分析,先脉络再细节。
将相关类分为两组,如图:

BaseServer是server基础类,定义server的基本处理运行与request处理机制,TCPServer直接继承它。
BaseRequestHandler是request处理的基础类,TCPServer的request处理类StreamRequestHandler直接继承它。
从类的设计上说,这里可以说时mixin的最佳实践了,什么是mixin?如何使用mixin?
A mixin is a special kind of multiple inheritance. There are two main situations where mixins are used:
1 You want to provide a lot of optional features for a class.
2 You want to use oRequestHandlerClassne particular feature in a lot of different classes.
在这些类的设计中始终围绕如何处理socket请求。通常,处理方式三种:
synchronous (one request is handled at a time)
forking (each request is handled by a new process)
threading (each request is handled by a new thread)
其中,BaseServer作为基础类,实现服务器的监听以及同步处理方法。初始化参数有两个:server_address和RequestHandlerClassserver_forever方法中使用select方式轮询,是否有客户端连接到服务器。
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()
如果有客户端连接,则使用同步的方式进行处理,最终调用一个RequestHandlerClass类进行处理。
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)
def process_request(self, request, client_address):
self.finish_request(request, client_address)
self.shutdown_request(request)
def finish_request(self, request, client_address):
self.RequestHandlerClass(request, client_address, self)
其中,TCPServer继承自BaseServer,加入了TCP的一些配置,但是运行机制时完全继承的。所以,此时的TCPServer就是第一种情情况。而多进程和多线程方式则通过mixin设计而成。以多线程的ThreadingTCPServer为例:
class ThreadingMixIn:
daemon_threads = False
def process_request_thread(self, request, client_address):
try:
self.finish_request(request, client_address)
self.shutdown_request(request)
except:
self.handle_error(request, client_address)
self.shutdown_request(request)
def process_request(self, request, client_address):
t = threading.Thread(target = self.process_request_thread,
args = (request, client_address))
t.daemon = self.daemon_threads
t.start()
在ThreadingMixIn类中,覆写process_request方法,对于每个request都创建一个线程进行处理。此时,多线程的情况只要这样:
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
注意,mixin类要放在前面,因为它覆写了TCPServer类的process_request方法。
在SocketServer完美体现了mixin两个设计原则:
ThreadingMixIn这个mixin类作为一个多线程的特性附加在了TCPServer上,同时这个特性又不仅仅是提供给TCPServer使用,还给UDPServer使用。
标签:http io ar 使用 sp for div on 2014
原文地址:http://www.cnblogs.com/dxm2025/p/4098086.html