localhostで、空きポート番号を選択するにはどうすればよいですか?


160

プロセス間通信を試してみましたが、Windowsで名前付きパイプを使用する方法がわからなかったので、ネットワークソケットを使用すると思いました。すべてがローカルで発生します。サーバーは別のプロセスでスレーブを起動し、いくつかのポートで待機します。スレーブは作業を行い、結果をマスターに送信します。どのポートが利用可能かを知るにはどうすればよいですか?ポート80または21でリッスンできないと思いますか?

私はPythonを使用していますが、それによって選択肢が減ります。

ありがとう!


1
ちなみに、ランダムまたはランダムなポート番号(できれば1024より大きい)を選択した場合は、おそらくそれが使用可能になります。他のプログラムがリッスンしていない限り、ポート80や21などを使用することもできます。常に、通常のシステムでは、使用されているポートはごく一部です。
David Z

19
ランダムなポートを選択することは良い考えではありません。OSにポートを選択させてください。
Corehpf 2009

回答:


224

特定のポートにバインドしたり、ポート0にバインドしたりしないでくださいsock.bind(('', 0))。次に、OSが使用可能なポートを選択します。を使用して選択したポートを取得し、sock.getsockname()[1]それをスレーブに渡して、スレーブが再び接続できるようにすることができます。


4
例については、stackoverflow.comsock.bind(('',0))
a / 2838309/3538289を

10
どのように奴隷に番号を伝えますか?鶏と卵の問題のように思えます。
セバスチャン

2
バインド後にスレーブを作成する場合は、作成時にパラメーターとして渡すだけです。あるいは、両方がアクセスできる共有メモリまたはファイルに書き込むこともできます。または、よく知られたポート番号を介してアクセスされる中央サーバーがそれを追跡することもできます。
mark4o 2016年

49

みんなが上で説明したことの抜粋のために:

import socket
from contextlib import closing

def find_free_port():
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
        s.bind(('', 0))
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        return s.getsockname()[1]

3
ローカルホストの場合:多分それs.bind(('localhost', 0))より良い
codeskyblue

3
また、良いことができますすぐに再利用あなたのreturn文の前にポートように次を追加するには:s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
jonEbird

1
@jonEbird socket.SO_REUSEADDRこの場合本当に役に立ちますか?私が読んだことから、バインドしようとしているソケットが持っSO_REUSEADDRていることだけが関係し、そのフラグが残っているソケットに設定されているかどうかは関係ありません。
Karl Bartel

41

ソケットをポート0にバインドします。1024〜65535のランダムな空きポートが選択されます。のgetsockname()直後に選択したポートを取得できますbind()


2

好きなポートでリッスンできます。通常、ユーザーアプリケーションは、1024以上のポート(65535まで)をリッスンする必要があります。リスナーの数が可変の場合の主なことは、アプリに範囲を割り当てることです。たとえば、20000〜21000、およびCATCH EXCEPTIONSです。これにより、コンピュータでポートが使用できない(つまり、別のプロセスで使用されている)かどうかがわかります。

ただし、この場合、バインドが失敗した場合にエラーメッセージを出力する限り、リスナーにハードコードされた単一のポートを使用しても問題はありません。

ほとんどのソケット(スレーブ用)を特定のポート番号に明示的にバインドする必要がないことにも注意してください。ここでのマスターのように、着信接続を待機するソケットのみをリスナーにしてポートにバインドする必要があります。ソケットが使用される前にポートが指定されていない場合、OSは使用可能なポートをソケットに割り当てます。マスターがデータを送信するスレーブに応答する場合、リスナーがデータを受信すると送信者のアドレスにアクセスできます。

これにUDPを使用すると思いますか?


0

後で使用するために空いているポートを見つけるだけでよい場合は、以前の回答に似たスニペットを以下に示します。

import socketserver

with socketserver.TCPServer(("localhost", 0), None) as s:
    free_port = s.server_address[1]

ポートが空いていることは保証されていないため、このスニペットとそれを使用するコードをループ内に配置する必要がある場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.