导语:大牛们常常说阅读源码是很低效的学习方法。但对我辈初学者而言,阅读源码却是掌握编程思想、编码规范的好途径。简而言之,读源码不是万能的,不读源码是万万不能的。

SocketServer是标准库中一个很具有代表性的库。它基于socket提供一套快速建立socket服务器的框架,并可以通过Mix-in的技巧让单线程服务器进化为多线程或多进程服务器。Socketserver.py里面的类很多,下面一个一个介绍并介绍它们之间关系。

BaseServer、TCPServer、UDPServer,前者是后两者的父类。在父类中实现了TCP与UDP服务器可以共用的方法,并留下了需要在子类中实现的抽象类。因此在实际工作中,我们一般不应该继承BaseServer类,除非你是为了自己去实现或重载某些方法。另外,还有UnixStreamServer和UnixDatagramServer分别继承自TCPserver和UDPServer。这两个带Unix字样的类是用来构建*nix下本地socket的服务器(本地socket访问速度更快,但只能用在本机的进程间通信)

接下来是ForkingMixIn和ThreadingMixIn两个混合类,它们都提供Server类中process_request方法的新实现,前者在处理每次用户连接的时候都会开启新的进程,而后者会开启新的线程。想要让Server类实现并发处理,只用利用多重继承即可。或者直接使用已经混合好的

class ForkingUDPServer(ForkingMixIn, UDPServer): pass
class ForkingTCPServer(ForkingMixIn, TCPServer): pass

class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass

最后没有介绍的是BaseRequestHandler、StreamRequestHandler、DatagramRequestHandler,同Server一样,前者是后两者的父类用来提供公用的方法

通常在使用SocketServer的时候我们只用自己实例化一个合适的Server类,并在实例化时传递其监听的IP、端口,以及之前继承自某个RequestHandler的类(需要自行实现hanle方法,作为server的请求处理器)

这里需要特别注意的:

1.IP和端口是作为一个元组传递的而不是两个单独的参数。

2.每个客户连接都会在hanle方法运行完之后被关闭,你如果不想关闭就需要重写Server中的def shutdown_request(self, request)方法

___________________我是华丽丽的分割线________________________

可以说这个标准库用起来还很方便的,但功能上还是有一些不足。

1.它没有提供各个hanle实例之间的通信机制,因此客户端互发消息还是需要自己实现一个观察者模型。

不过这个功能似乎也超过了SocketServer的工作职责了。我们可以自己实现,也可以使用python-message这个国产第三方库来进行线程间基于消息的编程。

2.它提供了多线程多进程的解决方案,但没有异步方案的server每次访问都是阻塞的

关于这点我感觉很遗憾,不过这个库也不是太复杂,大不了自己写一个异步的socketserver吧,自己动手丰衣足食!

 

因为本来就是是对源码的解读,所以这篇文章没有放什么代码。读者完全可以自己去标准库里翻翻看,注释写的真的很赞。


-*-python之禅-*-

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.

posted on 2013-05-06 16:09  MoonXue  阅读(487)  评论(0编辑  收藏  举报