0

ZeroMQ を使用して、同じマシンで実行中の他のプログラムと通信するプログラムを作成しています。衝突の可能性を避けるために、実行時にポート番号を選択したいと考えています。これを実現するために私が書いたコードの例を次に示します。

#!/usr/bin/perl -Tw

use strict;
use warnings;

my %in_use;
{
    local $ENV{PATH} = '/bin:/usr/bin';

    %in_use = map { $_ => 1 } split /\n/, qx(
        netstat -aunt          |\
        awk '{print \$4}'      |\
        grep :                 |\
        awk -F: '{print \$NF}'
    );
}

my ($port) = grep { not $in_use{$_} } 50_000 .. 59_999;

print "$port is available\n";

手順は次のとおりです。

  1. netstat -aunt を呼び出す

  2. 結果を解析する

  3. netstat リストに表示されない固定範囲の最初のポートを選択します。

これを達成するのにより適したシステムユーティリティはありますか?

4

2 に答える 2

2

まず、コードから、70000 から 79999 の間でポートを選択しようとしているように見えます。ポート番号は 65535 までしかないことを知っていますよね? :-)

アプローチにはいくつかの問題がありますが、確かにこの方法で実行できます。最初の問題は、netstat異なるオペレーティング システム間で出力が異なるため、移植可能にするのが難しいことです。2 番目の問題は、選択したポート番号にバインドできなかった場合に備えて、新しいポート番号を再検索しようとするループでコードをラップする必要があることです。これは、ポートが空いていることを確認する間に競合状態が発生するためです。そして実際にそれにバインドします。

使用しているライブラリでポート番号を 0 に指定できgetsockname()、ソケットがバインドされた後にソケットを呼び出すことができる場合は、それを行う必要があります。0 を使用すると、システムは任意の空いているポート番号を選択し、選択getsockname()したポートを見つけることができます。

それができない場合は、呼び出しnetstatを気にせず、ループ内で別のポート番号を見つけようとする方が実際にはおそらくより効率的です。成功したら、ループから抜け出します。失敗した場合は、ポート番号を 1 増やして、戻って、もう一度やり直してください。

于 2013-03-17T03:17:51.847 に答える
1
context = zmq.Context()
socket = context.socket(zmq.ROUTER)    
port_selected = socket.bind_to_random_port('tcp://*', min_port=6001, max_port=6004, max_tries=100)
于 2013-03-17T09:19:36.617 に答える