2017-06-14 39 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