首页 > 代码库 > Python 源码学习二(SocketServer)

Python 源码学习二(SocketServer)

SocketServer这个模块中定义的类比较多,但是设计比较清晰,我们以TCPServer为主线分析,先脉络再细节。

总体脉络

将相关类分为两组,如图:

总体脉络

服务器相关(上)

BaseServer是server基础类,定义server的基本处理运行与request处理机制,TCPServer直接继承它。

Request处理类RequestHandler(下)

BaseRequestHandler是request处理的基础类,TCPServer的request处理类StreamRequestHandler直接继承它。

TCPServer设计细节

从类的设计上说,这里可以说时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使用。

  • 相关文章推荐:
  • python 日志打印功能学习
  • python sys模块的一些常用功能
  • python beautifulsoup多线程分析并抓取网页
  • 本文来自:爱好Linux技术网
  • 本文链接:http://www.ahlinux.com/python/9109.html

Python 源码学习二(SocketServer)