2013-03-17 235 views
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列表上。

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

回答

0
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) 
+2

甜美!但是,它看起来像bind_to_random_port(...)方法只存在于Python驱动程序中。在查看时,我发现ZMQ v3支持通配符端口号,您可以跟随getsockopt(ZMQ_LAST_ENDPOINT)。 – ddoxey 2013-03-17 13:50:34

2

首先,从你的代码看起来你试图选择一个70000到79999之间的端口。你知道端口号只能达到65535,对吧? :-)

尽管这种方法存在一些问题,但您的确可以这样做。第一个问题是netstat的输出在不同的操作系统上有所不同,所以很难做到这一点。第二个问题是,您仍然需要将代码包装在一个循环中,该循环会再次尝试查找新的端口号,以防止无法绑定到所选的端口号,因为确定端口是空闲的并实际上绑定到它。

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

如果没有这样做,它可能实际上会更有效率,不用打电话netstat,只是试图找到一个循环中的不同端口号。如果你成功了,就从循环中解脱出来。如果失败,请将端口号增加1,然后返回,然后重试。

+0

哦,这有点愚蠢 - 纠正了无效的端口范围。 不,ZMQ不接受零端口号。 是的,这是让我犹豫的竞争条件。 – ddoxey 2013-03-17 05:14:57