web-dev-qa-db-ja.com

終了したプログラムによって開かれたままのソケットを閉じる方法は?

別のホスト上の別のPythonアプリケーションと通信するための簡単なTCPソケットを開くPythonアプリケーションがあります。時々、プログラムはエラーになるか、私は直接それを殺します。どちらの場合でも、ソケットは未知の時間の間開いたままになるかもしれません。

次にプログラムを実行するときにこのエラーが発生します。

_socket.error: [Errno 98] Address already in use
_

これで、プログラムは常に同じポートを使用しようとするため、まだ開いているように見えます。私はチェックし、プログラムがバックグラウンドで実行されていないと確信していますが、私のアドレスはまだ使用中です。

SO、プログラムをすぐに再利用できるように、どうすれば手動で(または別の方法で)ソケット/アドレスを閉じることができますか?

更新

マイクの答えに基づいて、socket(7)ページをチェックアウトし、SO_REUSEADDRを調べました。

_SO_REUSEADDR
    Indicates that the rules used in validating addresses supplied in a bind(2) call should
    allow reuse of local addresses.  For AF_INET sockets this means that a socket may bind,
    except when there is an active listening socket bound to the address.  When the listen‐
    ing  socket is bound to INADDR_ANY with a specific port then it is not possible to bind
    to this port for any local address.  Argument is an integer boolean flag.
_
37
Mr. Shickadance

ソケットの名前はs...であると仮定します...インターフェイスにバインドする前にサーバーのソケットにsocket.SO_REUSEADDRを設定する必要があります...これにより、TCPサーバー...

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ADDR, PORT))
37
Mike Pennington

ネットワークにTwistedを使用してみてください。マイクは正しい低レベルの答えを与えた、SO_REUSEADDR、しかし、彼はこれがWindows上で設定するための非常に良いオプションではないことに言及しませんでした。これは、Twistedが自動的に処理するようなものです。ソケットモジュールを直接使用する場合は注意が必要ですが、Twistedのような高レベルのライブラリを使用する場合は忘れることができる、この種の退屈な低レベルの詳細に関する他の多くの例があります。

11

ソケット、接続、およびポートを混同しています。ソケットは接続のエンドポイントであり、5タプル{プロトコル、ローカルIP、ローカルポート、リモートIP、リモートポート}です。強制終了されたプログラムのソケットはOSによって閉じられ、接続と同じです。接続の唯一の遺物は、ピアのソケットとピアホストの対応するポートです。したがって、実際に質問する必要があるのは、ローカルのport。を再利用する方法です。これに対して、他の回答に従ってSO_REUSEADDRが返されます。

5
user207421