SocketServer はネットワーク サービス フレームワークを作成します。 TCP、UDP、UNIX ストリーム、UNIX データグラムを介した同期ネットワーク要求を処理するクラスを定義します。
1. サーバーの種類
SocketServer には 5 つの異なるサーバー クラスがあります。
1.BaseServer は API を定義しており、インスタンス化や直接使用には使用されません。
2.TCPServerはTCP/IPソケット通信に使用されます。
3.UDPServer はデータグラム ソケットを使用します。
4.UnixStreamServer と UnixDatagramServer は Unix ドメイン ソケットを使用し、UNIX プラットフォーム上でインテリジェントに使用されます。
2. サーバー オブジェクト
リクエストされたアドレスとリクエスト処理クラス (インスタンスではない) をリッスンするサーバーを構築します。
1.class SocketServer.BaseServer
これは、モジュール内のすべてのサーバー オブジェクトのスーパー クラスであり、インターフェイスを定義し、実装のほとんどはサブクラスで完了します。
2.BaseServer.fileno
どのサーバーがリッスンしているかを示す整数のファイル記述子を返します。この関数は最も一般的に select.select() に渡され、複数のサービスが同じプロセスを監視できるようになります。
3.BaseServer.handle_request
この関数は、次のメソッドを順番に呼び出します。 get_request()、verify_request、および process_request。
ユーザーが handle() メソッドを指定して例外をスローした場合、 handle_error() メソッドが呼び出されます。
self.timeout 以内にリクエストが受信されなかった場合、handle_timeout() と handle_request() が戻ります。
4.BaseServer.serve_forever
BaseServer.serve_forever(poll_interval=0.5)、明示的な shutdown() リクエストまでリクエストを処理します。ローテーション トレーニングは、poll_interval 時間ごとに閉じられます。 self.timeout を無視します。スケジュールされたタスクを使用する必要がある場合は、他のスレッドを使用する必要があります。
5.BaseServer.shutdown
は、serve_forever() にループを停止するように指示します。
6.BaseServer.RequestHandlerClass
ユーザーリクエストハンドラークラス。リクエストごとにこのクラスのインスタンスを作成します。
3. サーバーの実装
サーバーを作成する場合、通常は既存のクラスを再利用して、カスタムのリクエスト処理クラスを提供するだけです。ニーズを満たさない場合にサブクラスをオーバーライドするための BaseServer メソッドがいくつかあります。
1.verify_request(reqeust, client_address): ブール値を返す必要があります。True が返された場合、リクエストは処理されます。False が返された場合、リクエストは拒否されます。この関数は、アクセス制御サービスを実装するためにオーバーライドできます。
2.process_request(request, client_address):finish_request を呼び出して、RequestHandlerClass() のインスタンスを作成します。必要に応じて、この関数はリクエストを処理するための新しいプロセスまたはコルーチンを作成できます。
3.finish_request(request, client_address): リクエスト処理インスタンスを作成します。 handle() を呼び出してリクエストを処理します。
4. リクエスト ハンドラー
リクエスト ハンドラーは、受信リクエストを受信し、実行するアクションを決定するための作業のほとんどを実行します。ハンドラーは、「プロトコル」(HTTP や XML-RPC など) にソケット層を実装する役割を果たします。受信リクエスト ハンドラーからリクエスト データを読み取り、処理し、応答を書き込みます。これをオーバーライドするには 3 つの方法があります。
1.setup(): リクエストのリクエスト ハンドラーを準備します。これはハンドルの前に初期化されて実行されます。
2.handle(): 実際のリクエスト作業を実行します。受信リクエストを解析し、データを処理し、応答を返します。
3.finish(): 作成された setup() をいつでもクリーンアップします。
5. 例
次の例は、tcp、udp、および非同期を示しています。
りー
3. 非同期の例
非同期ハンドラーは、ThreadingMixIn クラスと ForkingMixIn クラスを通じて構築できます。
import SocketServer class MyHandler(SocketServer.BaseRequestHandler): def handle(self): self.data = self.request.recv(1024).strip() print '{} wrote:'.format(self.client_address[0]) print self.data self.request.sendall(self.data.upper()) if __name__ == '__main__': HOST, PORT = 'localhost', 9999 server = SocketServer.TCPServer((HOST, PORT), MyHandler) server.serve_forever()
(1) SocketServerTCPサーバーを作成します
import SocketServer class MyHandler(SocketServer.BaseRequestHandler): def handle(self): data = self.request[0].strip() socket = self.request[1] print '{} wrote:'.format(self.client_address[0]) print data socket.sendto(data.upper(), self.client_address) if __name__ == '__main__': HOST, PORT = 'localhost', 9999 server = SocketServer.UDPServer((HOST, PORT), MyHandler) server.serve_forever()
(2) SocketServerTCを作成しますPクライアント
import socket
import threading
import SocketServer
class MyHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
curr_thread = threading.current_thread()
response = '{}: {}'.format(curr_thread.name, data)
self.request.sendall(response)
class Server(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
def client(ip, port, message):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
try:
sock.sendall(message)
response = sock.recv(1024)
print 'Received: {}'.format(response)
finally:
sock.close()
if __name__ == '__main__':
HOST, PORT = 'localhost', 0
server = Server((HOST, PORT), MyHandler)
ip, port = server.server_address
serer_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
print 'Server loop running in thread:', server_thread.name
client(ip, port, 'Hello World 1')
client(ip, port, 'Hello World 2')
client(ip, port, 'Hello World 3')
server.shutdown()
server.server_close()
Python の SocketServer モジュールがネットワーク リクエストを処理する方法について詳しくは、PHP 中国語 Web サイトの関連記事に注目してください。