如何选择端口号



我正在编写一个使用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 availablen";

程序如下:

  1. 调用netstat -aunt

  2. 解析结果

  3. 选择固定范围内的第一个端口,该端口没有出现在netstat列表中。

是否有更适合完成此任务的系统实用程序?

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)

首先,从您的代码中,看起来您正在尝试选择70000和79999之间的端口。你知道端口号最多只能达到65535,对吧?: -)

您当然可以这样做,尽管这种方法存在一些问题。第一个问题是netstat输出在不同的操作系统之间是不同的,所以很难移植。第二个问题是,您仍然需要将代码包装在一个循环中,该循环在无法绑定到所选端口号的情况下再次尝试查找新端口号,因为在确定端口空闲和实际绑定端口之间存在竞争条件。

如果您正在使用的库允许您将端口号指定为0,并允许您在绑定套接字后调用getsockname(),那么您应该这样做。使用0可以使系统选择任何空闲端口号,使用getsockname()可以找出它选择的端口。

如果做不到这一点,实际上不调用netstat可能会更有效,只是尝试在循环中找到不同的端口号。如果你成功了,就跳出这个循环。如果失败,将端口号增加1,返回,然后再试一次。

最新更新