天天看點

10.python網絡程式設計(socket server 實作并發 part 2)

一、基于tcp的socket通信的基本原理分析。

基于tcp的socket通信,主要依靠兩個循環,分别是連接配接循環和通信循環。

這個前面的文章有寫過,在這裡就不再重複了。

二、socketserver實作多并發的原理分析。

1.server類:

10.python網絡程式設計(socket server 實作并發 part 2)

2.reques類。

10.python網絡程式設計(socket server 實作并發 part 2)

類繼承關系:

10.python網絡程式設計(socket server 實作并發 part 2)
10.python網絡程式設計(socket server 實作并發 part 2)

示例代碼:

分析開始:

結合上面的例子,還有類關系圖一塊看。

查找屬性的順序:ThreadingTCPServer->ThreadingMixIn->TCPServer->BaseServer

通過ThreadingTCPServer 這個類,執行個體化出一個ftpserver對象。

1.2 先從ThreadingTCPServer這個類中找__init__方法,SocketServer的源碼中可以看到,它本身并沒有__init__方法,這時候就從ThreadingTCPServer所繼承的兩個父類中去找。從源碼中可以看到ThreadingTCPServer一共繼承了兩個父類,分别是ThreadingMixIn和TCPServer,其中ThreadingMixIn中也沒有__init__方法,最終在TCPServer下找到了__init__,此時執行TCPServer下的__init__方法。

       1.3 TCPServer下的__init__方法一共做了四件事,分别是執行了BaseServer類下的__init__方法,創                                    建了socket對象,綁定了IP位址和端口(bind),以及開始listen監聽。

        BaseServer類下的__init__方法,做了兩件事,為建立出來的對象添加了兩個屬性,分别                                            是server_address和RequestHandlerClass,其中server_address是服務端綁定的ip位址和端                        口,RequestHandlerClass是前面我們自己建立的FtpServer類。

        (完成了bind和listen操作是因為執行了server_bind和server_active)

    2.Serve_forever 實作連接配接循環。

        2.1前面說了,ftpserver這個對象是由ThreadingTCPServer這個類建立出來的,是以說,預設情況下ftpserver這個對象本身,以及ThreadingTCPServer這個類都沒有Serve_forever這個方法,依舊按照上面的套路,閱讀源碼,從ThreadingTCPServer繼承的父類中去找,分别是ThreadingMixIn和TCPServer,在這兩個父類中都沒有找到,接着去看ThreadingMixIn和TCPServer繼承的父類....關于繼承順序的概念在這也不再贅述.....最終在BaseServer中找到了Serve_forever這個方法。

    2.2serve_forever下主要執行self._handle_request_noblock()進而執行request, client_address = self.get_request()(就是TCPServer中的self.socket.accept()),然後執行self.process_request(request, client_address)

在ThreadingMixIn中找到process_request,開啟多線程應對并發,進而執行process_request_thread,執行self.finish_request(request, client_address)。

    2.3上述四部分完成了連結循環,本部分開始進入處理通訊部分,在BaseServer中找到finish_request,觸發我們自己定義的類的執行個體化,去找__init__方法,而我們自己定義的類沒有該方法,則去它的父類也就是BaseRequestHandler中找....

最後總結下建立socketserver的幾個步驟。

First, you must create a request handler class by subclassing the BaseRequestHandlerclass and overriding its handle() method; this method will process incoming requests.   

首先你必須建立一個類,這個類必須是BaseRequestHandler的子類,并且這個類必須要有一個handle方法,這個方法用來處理連接配接進來的請求。

2.Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class.

其次你必須執行個體化一個伺服器類,在執行個體化的過程中,需要傳入服務端位址 以及 那個請求句柄的類。

3.Then call the handle_request() or serve_forever() method of the server object to process one or many requests.

然後,執行伺服器對象的handle_request()或 serve_forever()方法 ,來處理一個或多個請求。

4.Finally, call server_close() to close the socket.

最後,執行server_close()這個方法關閉套接字。

      本文轉自蘇浩智 51CTO部落格,原文連結:http://blog.51cto.com/suhaozhi/1923787,如需轉載請自行聯系原作者