2017-06-14 69 views
1

我想解析主機名到這是所有罰款採用Socket一個IP地址如下:Perl的主機到IP解析

$ip = gethostbyname($host) or die "Can't resolve ip for $host.\n"; 
$ip = inet_ntoa(inet_aton($host)); 

這工作得很好,直到它擊中的主機名不再解析到一個IP和代碼只是停止。我如何讓我的腳本繼續處理其餘的IP地址以解析主機名。 理想情況下,我會簡單地將$ip變量設置爲""

我試過,即使沒有die命令,代碼仍然停止,當它無法解析名稱到IP。

+0

嘗試使用'eval' – AbhiNickz

回答

3

gethostbyname的超時時間非常非常長。我認爲你在看到它花費很長時間之前就殺了這個程序。看來你真的需要更短的超時時間。 †

您可以使用alarm設置自己的超時值。當它關閉時,SIGALRM信號被傳送到進程,並在默認情況下終止它。因此,我們爲該信號設置了一個處理程序,其中發佈die,從而將其變爲例外。這是eval -ed,我們得到控制權。

eval { 
    local $SIG{ALRM} = sub { die "Timed out" }; 

    alarm 5; # or what you find most suitable 

    # your code that may need a timeout 

    alarm 0; 
}; 
if ([email protected] and [email protected] !~ /Timed out/) { die } # re-raise if it was something else 

if ([email protected] and [email protected] =~ /Timed out/) { # test 
    print "We timed out\n"; 
} 

如果你的代碼在不到5秒完成我們得到alarm 0;其取消以前的報警,程序繼續。否則,我們收到SIGALRM,將其處理並製作爲die。由於我們在eval之內,因此被捕獲並且控件在塊之後下降。我們測試die是否確實是由於我們的警報,如果不是,我們重新提高它。

另請參閱this post瞭解更多評論,請搜索更多。


†  模塊IO::Socket中存在的Timeout功能用於連接,而不用於DNS查找,這是此處的罪魁禍首。感謝Steffen Ullrich的評論。

+0

IO :: Socket :: *中的超時僅適用於套接字活動,即連接。它不包括使用gethostbyname或gethostbyaddr進行阻止的DNS查找。 –

+0

@SteffenUllrich謝謝!我看到那個地方,但不確定。編輯到帖子。 – zdim

+0

@ user2593348請讓我知道這是如何工作,或如果更多的解釋將是有用的。 – zdim