socketserver-クラス変数をオーバーライドせずに機能していない既存のポート番号を再バインドするためのallow_reuse_address

Rohit

socketserverモジュールを使用して単純なソケットサーバーを作成していますが、1つだけ小さなことを除いて、すべて正常に動作しているようです。サーバーをあるポートにバインドしてからserver.allow_reuse_address = True、カーネルが基になるポートを解放するのを待たずに、同じポートを再利用するように設定しました。ただしserver.allow_reuse_address = True、サーバーインスタンスの作成後に変数を変更すると機能しませんが、サーバーのカスタムクラスを作成してからその変数をオーバーライドすると、すべてが機能します。

以下は私のコードです。

import socketserver
import sys

class MyTCPRequestehandler(socketserver.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024)
        while self.data:
            print('Received {} from {}'.format(self.data.decode().strip(), self.client_address))
            self.request.send(self.data.upper())
            self.data = self.request.recv(1024)


if __name__ == '__main__':
    try:
        server = socketserver.TCPServer(('', 12345), MyTCPRequestehandler)
        ip, port = server.server_address
        server.allow_reuse_address = True
        print(server.allow_reuse_address)
        print('Server listening on port {}'.format(port))
        # server.handle_request()
        server.serve_forever()
    except KeyboardInterrupt:
        sys.exit()

切断した直後にアプリケーションを再実行すると、このエラーが発生します

File "/Documents/PythonPrograms/network-modules/socketServer/simplesocketserver.py", line 16, in <module>
    server = socketserver.TCPServer(('', 12345), MyTCPRequestehandler)
  File "/spare/ssd/rbhanot/anaconda3/lib/python3.6/socketserver.py", line 453, in __init__
    self.server_bind()
  File "/spare/ssd/rbhanot/anaconda3/lib/python3.6/socketserver.py", line 467, in server_bind
    self.socket.bind(self.server_address)
OSError: [Errno 98] Address already in use

しかし、私が以下のようなことをすれば、すべてがうまくいきます。

class MyTcpServer(socketserver.TCPServer):
    allow_reuse_address = True

    def __init__(self, address, request_handler_class):
        self.address = address
        self.request_handler_class = request_handler_class
        super().__init__(self.address, self.request_handler_class)    

だから私はここで何が欠けていますか?

ハンヌ

これは、予想され、文書化された動作です。https://svn.python.org/projects/python/trunk/Lib/SocketServer.pyから

派生クラスまたはインスタンスによってオーバーライドされる可能性のあるクラス変数:

  • タイムアウト
  • address_family
  • socket_type
  • allow_reuse_address

そして、ソースコードをさらに調べると、その理由がわかります。クラスinitはserver_bind()、を呼び出します。これは、allow_reuse_address変数をチェックし、setsockopt必要に応じて実行する関数です。

後で変更した場合、インスタンスの初期化後にそれ以上のチェックは行われません。つまり、変更は何にも影響しません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ