Python の SocketServer モジュールがネットワーク リクエストを処理する方法を説明する

高洛峰
リリース: 2017-03-01 14:17:58
オリジナル
1816 人が閲覧しました

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()
ログイン後にコピー


4.SocketServerはクライアントとサーバー間のノンブロッキング通信を実装します

(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 サイトの関連記事に注目してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!