【问题标题】:Perl Host to Ip ResolutionPerl 主机到 IP 解析
【发布时间】:2017-11-15 22:42:48
【问题描述】:

我想将一个主机名解析为一个 IP 地址,使用 Socket 可以解决以下问题:

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

这工作正常,直到它遇到不再解析为 IP 的主机名并且代码停止。如何让我的脚本继续处理要解析的主机名的剩余 ip。 理想情况下,我只需将$ip 变量设置为等于""

即使没有 die 命令,我也尝试过,但当它无法将名称解析为 ip 时,代码仍然会停止。

【问题讨论】:

  • 试试eval

标签: perl gethostbyname


【解决方案1】:

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 ($@ and $@ !~ /Timed out/) { die }  # re-raise if it was something else

if ($@ and $@ =~ /Timed out/) {  # test
    print "We timed out\n";
}

如果您的代码在不到5 秒内完成,我们会到达alarm 0;,它会取消先前的警报,程序继续。否则,SIGALRM 被发射,但被处理并制成die,即eval-ed,因此信号被完全捕获,控制权下降到块之后。我们测试die 是否确实是由于我们的警报,如果不是,我们重新发出警报。

更多cmets,另见this post,请搜索。


模块 IO::Socket 中存在的 Timeout 功能用于连接而不是用于 DNS 查找,这是罪魁祸首。感谢Steffen Ullrich 的评论。

【讨论】:

  • IO::Socket::* 中的超时仅适用于套接字活动,即连接。它不包括使用 gethostbyname 或 gethostbyaddr 阻止的 DNS 查找。
  • @SteffenUllrich 谢谢!我在某个地方看到过,但不确定。已编辑到帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 2016-07-05
  • 2013-11-29
  • 2011-03-12
  • 2011-01-10
  • 1970-01-01
相关资源
最近更新 更多