2013-03-17 232 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