Python SocketServer.pyソース分析(一)

5597 ワード

BaseServerとBaseRequestHandler
Pythonは、ネットワークプログラミングのためにより高度なパッケージを向上させた.SocketServer.pyは多くのネットワークサービスのクラスを提供しています.それらのデザインは優雅です.Pythonはネットワークサービスを2つの主要なクラスに抽象化し,1つはサーバクラスであり,接続関連のネットワーク操作を処理するために用いられ,もう1つはRequestHandlerクラスであり,データ関連の操作を処理するために用いられる.さらに、サーバを拡張し、マルチプロセスまたはマルチスレッドを実現するための2つのMixInクラスを提供します.ネットワーク・サービスを構築する場合、サーバとRequestHandlerは別々ではありません.RequestHandlerのインスタンス・オブジェクトは、サーバ内でサーバと連携して動作します.
モジュールを変更する主ないくつかのServer関係は以下の通りである.
        +------------+
        | BaseServer |
        +------------+
              |
              v
        +-----------+        +------------------+
        | TCPServer |------->| UnixStreamServer |
        +-----------+        +------------------+
              |
              v
        +-----------+        +--------------------+
        | UDPServer |------->| UnixDatagramServer |
        +-----------+        +--------------------+

BaseServer分析
BaseServerは__init__によって初期化され、サービスを提供します.foreverとhandler_requestメソッド.
初期化
    def __init__(self, server_address, RequestHandlerClass):
        """Constructor.  May be extended, do not override."""
        self.server_address = server_address
        self.RequestHandlerClass = RequestHandlerClass
        self.__is_shut_down = threading.Event()
        self.__shutdown_request = False
__init__ソースコードは簡単です.主な役割は、serverオブジェクトを作成し、serverアドレスと処理要求のclassを初期化することです.ソケットプログラミングに詳しいのはよく知っているはずだserver_addressは、ホストとポートを含むメタグループです.
serve_forever
サーバオブジェクトを作成したら、サーバオブジェクトを使用して無限ループを開く必要があります.次に、serve_を分析します.foreverのソース.
    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()

serve_foreverはパラメータpollを受け入れますintervalは、selectポーリングの時間を表すために使用されます.次に無限ループに入り、select方式を呼び出してネットワークIOの傍受を行う.
select関数が返され、IO接続またはデータがあることを示す場合、_が呼び出されます.handle_request_noblockメソッド.
_handle_request_noblock
    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)


_handle_request_Noblockメソッドは、要求の処理を開始し、非ブロックである.このメソッドはget_を介してrequestメソッドは、そのサブクラスで実装される接続を取得します.接続が得られたらverify_を呼び出すリクエストメソッド検証リクエスト.検証に合格しました.processを呼び出します.リクエスト処理リクエスト.途中でエラーが発生した場合はhandle_を呼び出します.Error処理エラー、shutdown_requestは接続を終了します.
verify_request
    def verify_request(self, request, client_address):
        return True

この方法はrequestを検証し,通常はクラスに書き換えられる.簡単にTrueに戻り、プロセスに入ります.リクエストメソッドはリクエストを処理します.
process_request
    def process_request(self, request, client_address):
        self.finish_request(request, client_address)
        self.shutdown_request(request)

process_requestメソッドはmixinのエントリであり,MixInサブクラスはこのメソッドを書き換えることでマルチスレッドまたはマルチプロセスの構成を行う.呼び出しfinish_requestはリクエストの処理を完了し、shutdown_を呼び出す.リクエスト終了リクエスト.
finish_request
    def finish_request(self, request, client_address):
        self.RequestHandlerClass(request, client_address, self)

finish_リクエストメソッドはリクエストを処理します.requestHandlerオブジェクトを作成し、requestHandlerで具体的な処理を行います.
BaseRequestHandler解析
すべてのrequestHandlerはBaseRequestHandlerベースクラスを継承します.
    def __init__(self, request, client_address, server):
        self.request = request
        self.client_address = client_address
        self.server = server
        self.setup()
        try:
            self.handle()
        finally:
            self.finish()

クラスは各リクエストを処理します.オブジェクトを初期化するときにリクエストリクエストリクエストオブジェクトを設定します.次にsetupメソッドを呼び出し、サブクラスはsocket接続を処理するためにメソッドを書き換えます.次はhandlerとfinishメソッドです.リクエストの処理はすべてhandlerメソッドを書き換えることができます.
これで、Pythonが提供するサーバ方式全体が紹介されます.要約すると、ネットワークIOを処理するためにBaseServerが必要であり、内部にrequestHandlerオブジェクトを作成し、すべての特定のリクエストを処理する必要があります.

BaseServer - BaseRequestHandler

__init__(server_address, RequestHandlerClass): 
    BaseServer.server_address
    BaseServer.RequestHandlerClass
    
serve_forever(): 

    select() 

    BaseServer._handle_request_noblock()

        BaseServer.get_request() -> request, client_addres

        BaseServer.verify_request()

            BaseServer.process_request()

                BaseServer.process_request()

                    BaseServer.finish_request()

                        BaseServer.RequestHandlerClass()

                            BaseRequestHandler.__init__(request)
            
                                BaseRequestHandler.request
                                BaseRequestHandler.client_address = client_address

                                BaseRequestHandler.setup()

                                BaseRequestHandler.handle()

                    BaseServer.shutdown_request()
          
                        BaseServer.close_request()

            BaseServer.shutdown_request()
          
                BaseServer.close_request()