原文來自http://docs.python.org/library/socketserver.htmlhtml
1、簡介python
Python的SocketServer模塊簡化了編寫網絡服務器,他有四個基本的服務器類:「一、TCPServer二、UDPServer 三、UnixStreamServer 四、UnixDatagramServer」服務器
一、TCPServer使用的互聯網TCP協議,它提供連續的客戶端和服務器之間的數據流。
二、UDPServer使用離散的數據包的信息,能夠不按順序到達
網絡
三、UnixStreamServer和UnixDatagramServer 是不常使用的,這兩個類是很類似的app
2、基本知識異步
一般這四個類在處理請求時必須完成整個過程後才能處理下一個請求。(若是每一個請求的處理過程須要很長的時間才能完成或者它傳回大量數據到客戶端時很是緩慢時,另外一個請求只能等待)。要解決這個問題能夠建立一個單獨的進程或線程來處理每一個請求。 ForkingMixIn和ThreadingMixIn混合類可用於支持異步操做。socket
建立一個服務器須要幾個步驟:
一、首先你要建立一個請求處理程序的類,調用SocketServer類中的BaseRequestHandler子類,並重寫它的handle()方法,這個方法會處理傳入的請求
二、你必須實例化一個服務器類,它經過服務器地址和請求來處理程序類。
async
三、用handle_request() or serve_forever()方法來處理一個或多個請求。ide
3、繼續ui
爲防止線程在運行中忽然掛掉了,因此在
繼承ThreadingMixIn過程時
必須將
ThreadingMixIn類的屬性
定義爲
守護線程,這樣服務器就知道是否應該等特
線程
或終止服務器,因此要明確設置。若是你想線程都是執行完自主關閉的(默認是False)。這就意味着Python 不會退出,直到全部的線程
ThreadingMixIn都結束。
4、注意
在Python3中,本模塊爲socketserver模塊。在Python 2.x中,本模塊爲SocketServer模塊。因此在用import導入時,要分狀況導入,不然會報錯。導入的代碼以下:
try: import socketserver #Python 3 except ImportError: import SocketServer #Python 2
5、
+ ------------ + BaseServer | + ------------ + | v + ----------- + + ------------------ + | TCPSERVER | ------- | UnixStreamServer | + ----------- + + ------------------ + | v + ----------- + + -------------------- + | UDPServer | -------> | UnixDatagramServer | + ----------- + + -------------------- +
class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
The mix-in class must come first, since it overrides a method defined in UDPServer. Setting the various attributes also change the behavior of the underlying server mechanism.
To implement a service, you must derive a class from BaseRequestHandler and redefine its handle() method. You can then run various versions of the service by combining one of the server classes with your request handler class. The request handler class must be different for datagram or stream services. This can be hidden by using the handler subclasses StreamRequestHandler or DatagramRequestHandler.
Of course, you still have to use your head! For instance, it makes no sense to use a forking server if the service contains state in memory that can be modified by different requests, since the modifications in the child process would never reach the initial state kept in the parent process and passed to each child. In this case, you can use a threading server, but you will probably have to use locks to protect the integrity of the shared data.
On the other hand, if you are building an HTTP server where all data is stored externally (for instance, in the file system), a synchronous class will essentially render the service 「deaf」 while one request is being handled – which may be for a very long time if a client is slow to receive all the data it has requested. Here a threading or forking server is appropriate.
In some cases, it may be appropriate to process part of a request synchronously, but to finish processing in a forked child depending on the request data. This can be implemented by using a synchronous server and doing an explicit fork in the request handler class handle() method.
Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor fork() (or where these are too expensive or inappropriate for the service) is to maintain an explicit table of partially finished requests and to use select() to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be connected for a long time (if threads or subprocesses cannot be used). See asyncore for another way to manage this.