33

Python の localhost でランダムに開いている TCP ポートを取得したいと考えています。最も簡単な方法は何ですか?

4

5 に答える 5

68

私の現在の解決策:

def get_open_port():
        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(("",0))
        s.listen(1)
        port = s.getsockname()[1]
        s.close()
        return port

あまり良くなく、100%正確でもありませんが、今のところは機能します。

于 2010-05-14T23:48:12.003 に答える
18

空いているポートは、オペレーティング システムによって選択されたポートにソケットをバインドすることによって見つけることができます。オペレーティング システムがポートを選択した後、ソケットを破棄できます。ただし、このソリューションは競合状態に耐性がありません。空きポート番号を取得してからこのポートを使用するまでの短い時間に、他のプロセスがこのポートを使用する可能性があります。

import socket

def find_free_port():
    with socket.socket() as s:
        s.bind(('', 0))            # Bind to a free port provided by the host.
        return s.getsockname()[1]  # Return the port number assigned.

https://godbolt.org/z/fs13K13dG

于 2016-03-31T11:16:02.993 に答える
3

私は実際に私のプログラムの1つで以下を使用しています:

port = random.randint(10000,60000)

もちろん、これはあなたが持っているコードよりも衝突を起こしやすいです。しかし、私はそれで問題を抱えたことはありません。ポイントは、いつでも、これらの大きな番号のポートのほとんどが使用されておらず、無作為に 1 つを選択した場合、別のプロセスと競合する可能性はほとんどないということです。回答に投稿したソリューションのようなことを行う場合 (ソケットを開いてそのポート番号を取得する)、ポートが競合しないことはほぼ確実です。したがって、これが (一般に公開するものではなく) 自分のためだけに使用するものである場合は、本当に防弾のソリューションを考え出す価値があるかどうかを考えてください。おそらく、それは決して違いを生むことはありません。

あなたの質問に対するマルセロ・カントスのコメントに動機付けられて、このような場合の標準的な解決策は、ポートを使用するプロセスをそれにバインドし、その情報を必要とする他のプログラムと共有することです。通常、ポート番号を含む一時ファイルをファイルシステムの標準的な場所に書き込むようなことを行います。あなたが取り組んでいるプロセスはそれをしないので、ある意味であなたが思いついた解決策はちょっとしたハックになります. 繰り返しますが、それが自分の使用のためだけであれば、おそらく問題ありません。

于 2010-05-15T00:12:29.537 に答える