SO_REUSEADDR

いつまで待ったらSO_REUSEADDRがデフォルトで有効になるのか。このフラグを立てずにサーバを書いている人がいるとは思えない。何度Address already in useを見てうんざりしたことか。

Pythonの場合、$pythonlib/SocketServer.pyにあるSocketServer.TCPServerallow_reuse_addressをTrue(1)に設定すればよい(デフォルトはFalse(0)だ)。これはクラス変数であるから、派生クラスで値をTrueに設定すればsocket()bind()の間で

socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

を呼んでくれる。つまり、例えばSimpleXMLRPCServerだと、

import SimpleXMLRPCServer
SimpleXMLRPCServer.SimpleXMLRPCServer.allow_reuse_address=True
sv=SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 9999))

という感じになる。BaseHTTPServer.pyのHTTPServerではクラス定義の部分でデフォルトでTrueに設定している。ここは、あえてTCPServerのレベルでデフォルトをTrueに設定すべきと思う。

…まあ、こんなこと書くのは、書き忘れて使えるようになるのを待ってるからなんですけどね(笑)

(追記) 2004-06-08 08:50

いまさら補足。後で使うほうのプログラムでTIME_WAIT状態のソケットを破棄してアドレスを再使用するというものなので、後で起動したほうのプログラムがSO_REUSEADDRに設定すればよい。本来は待たなくてもよい状況なのです。

そういう性格のものなので、setsockopt()をsocket()とbind()の間で呼ばなければならず、後で呼んでも効果はない。最初はTCPServer(すでにlisten中)のインスタンスに対してsetsockopt()を呼んでしまって効果のなさに戸惑う。

というわけで、Pythonの実装がこれをクラス変数にしたというのは当然なのである(ついでに言えば、Pythonではクラス変数とインスタンス変数に区別はないはず)。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です