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不同操作系统之间的输出不同,因此很难移植。第二个问题是您仍然需要将代码包装在一个循环中,该循环再次尝试查找新端口号,以防无法绑定到所选端口号,因为在确定端口空闲之间存在竞争条件并实际绑定到它。

如果您使用的库允许您将端口号指定为 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 回答