我试图从sql数据库中的一列中ping大约100个主机 我正在使用 使用Net :: Ping; 使用Array :: Average;模块
是否有替代方案可以直接从perl脚本中提取丢包,rtt(min,max,avg)参数?
这是我的伪代码
$p = Net::Ping->new('icmp');
$p->hires();
$host = "www.xyz.com";
print "$host \n";
@rtt= 0;
$j=0;
for ($i=0;$i<5;$i++) {
($ret, $duration, $ip) = $p->ping($host, 5);# wait time 5
if($ret){
printf("$host [ip: $ip] $duration ms\n");
$rtt[$i] = $duration;
}
else{
$j++;
#$p->nack( $failed_ack_host );
}}
print " @rtt\n";
$rtt= average(@rtt);
print "The average rtt is $rtt \n";
$Packet_Loss = ((5-$j)/5)*100;
print "$Packet_Loss\%\n";
答案 0 :(得分:0)
`净::平&#39;似乎没有返回RTT等。您可以尝试发出系统ping命令,并自己处理结果:
$result = `ping -c 10 $host`;
...然后为您需要的字段解析$result
。
答案 1 :(得分:0)
查看文档和源代码,Net::Ping
模块只执行一次&#34; ping&#34;每次调用ping()
方法时。它没有保留任何内部状态&#34;基于之前通话的成功与否。这种方法的优点是它简单而且没有废话。但是,如果您想要汇总结果,那么您必须自己完成,就像您已经发现的那样。
虽然调用外部ping
命令很诱人,但你需要确定你想要的是什么:你不需要做一些数学,但是你会变得更加系统化特定的(并非所有系统都有ping
命令),你依赖于一些关于传递给命令的选项和输出格式的假设,你增加了创建一个的开销。新进程,并且您将面临可能永远无法控制的风险(某些ping
命令只会在您中断它们之前运行)。就个人而言,我坚持你正在采取的方法。
此外,在上面的特定代码中,请查看您如何存储结果。如果前三个和最后一个ping成功,比如说,但是最后一个ping没有,那么你将一个数组传递给average()
并带有一个未定义的值,这可能不是你想要的。我建议这样的事情:
my @rtt;
my $attempts = 5;
foreach (1 .. $attempts) {
my ($ret, $duration, $ip) = $p->ping($host, 5); # timeout after 5 seconds
if ($ret) {
print "$host [ip: $ip] $duration ms\n";
push @rtt, $duration;
} else {
$j++;
}
}
⋮
if (@rtt) {
my $rtt= average(@rtt);
print "The average rtt is $rtt \n";
} else {
print "No responses to ping\n";
}
这也解决了一两个其他角落情况。