Python SocketServer.pyソース分析(一)
5597 ワード
BaseServerとBaseRequestHandler
Pythonは、ネットワークプログラミングのためにより高度なパッケージを向上させた.SocketServer.pyは多くのネットワークサービスのクラスを提供しています.それらのデザインは優雅です.Pythonはネットワークサービスを2つの主要なクラスに抽象化し,1つはサーバクラスであり,接続関連のネットワーク操作を処理するために用いられ,もう1つはRequestHandlerクラスであり,データ関連の操作を処理するために用いられる.さらに、サーバを拡張し、マルチプロセスまたはマルチスレッドを実現するための2つのMixInクラスを提供します.ネットワーク・サービスを構築する場合、サーバとRequestHandlerは別々ではありません.RequestHandlerのインスタンス・オブジェクトは、サーバ内でサーバと連携して動作します.
モジュールを変更する主ないくつかの
BaseServer分析
BaseServerは
初期化
serve_forever
サーバオブジェクトを作成したら、サーバオブジェクトを使用して無限ループを開く必要があります.次に、serve_を分析します.foreverのソース.
serve_foreverはパラメータpollを受け入れますintervalは、selectポーリングの時間を表すために使用されます.次に無限ループに入り、select方式を呼び出してネットワークIOの傍受を行う.
select関数が返され、IO接続またはデータがあることを示す場合、_が呼び出されます.handle_request_noblockメソッド.
_handle_request_noblock
_handle_request_Noblockメソッドは、要求の処理を開始し、非ブロックである.このメソッドはget_を介してrequestメソッドは、そのサブクラスで実装される接続を取得します.接続が得られたらverify_を呼び出すリクエストメソッド検証リクエスト.検証に合格しました.processを呼び出します.リクエスト処理リクエスト.途中でエラーが発生した場合はhandle_を呼び出します.Error処理エラー、shutdown_requestは接続を終了します.
verify_request
この方法はrequestを検証し,通常はクラスに書き換えられる.簡単にTrueに戻り、プロセスに入ります.リクエストメソッドはリクエストを処理します.
process_request
process_requestメソッドはmixinのエントリであり,MixInサブクラスはこのメソッドを書き換えることでマルチスレッドまたはマルチプロセスの構成を行う.呼び出しfinish_requestはリクエストの処理を完了し、shutdown_を呼び出す.リクエスト終了リクエスト.
finish_request
finish_リクエストメソッドはリクエストを処理します.requestHandlerオブジェクトを作成し、requestHandlerで具体的な処理を行います.
BaseRequestHandler解析
すべてのrequestHandlerはBaseRequestHandlerベースクラスを継承します.
クラスは各リクエストを処理します.オブジェクトを初期化するときにリクエストリクエストリクエストオブジェクトを設定します.次にsetupメソッドを呼び出し、サブクラスはsocket接続を処理するためにメソッドを書き換えます.次はhandlerとfinishメソッドです.リクエストの処理はすべてhandlerメソッドを書き換えることができます.
これで、Pythonが提供するサーバ方式全体が紹介されます.要約すると、ネットワークIOを処理するためにBaseServerが必要であり、内部にrequestHandlerオブジェクトを作成し、すべての特定のリクエストを処理する必要があります.
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()