我有一个简单的脚本,可以定期验证(每隔几秒一次)是否有来自该服务器的互联网连接。要明确的是,它不是要检查外部站点/服务/服务器是否还活着。作为可靠的互联网目的地,我使用谷歌,雅虎等网站的IP。通常我使用3个目的地(局域网,ISP网络,外部ISP)
我当前对此负责的代码只是对ping
的简单而肮脏的调用:
my $pingResponse = `ping -c 1 -w 1 123.123.123.123`;
my $isConnected = parsePingResponse($pingResponse);
它似乎有效,但我确信这不是完成此任务的正确/最佳方式。至少有3个缺点:外部系统调用,它很慢,它有一个相对较长的截止日期 1秒。
所以,我的问题是:如何以 perlish 方式简单有效地实现 ping 功能,以验证互联网连接是否存在?
(我认为LWP是一种矫枉过正。如果一个站点或一个页面可用,那就不重要了,就好像可以访问一些外部IP一样。可能它应该是涉及低级网络的简单事项)
答案 0 :(得分:6)
这样做的方法是Net::Ping。
my $p = Net::Ping->new;
if ($p->ping("123.123.123.123", 1)) {
print "Host is reachable\n";
}
如果您希望命令运行得更快,则超时可能是浮点数(例如0.5)。您需要选择适合您需求的超时;更高的超时更可能是关于互联网连接的正确,但需要更长的时间。
答案 1 :(得分:2)
上面的rjh给出的示例在许多情况下不起作用,因为他没有正确初始化构造函数。 以下示例可能有所帮助:
use Net::Ping;
my $p = Net::Ping->new("icmp");
while(1){
printf "Checking for internet\n";
if ($p->ping("www.google.com")){
printf "Internet connection is active!\n";
sleep 1;
last; #break out of while loop if connection found
}
else{
printf "Internet connection not active! Sleeping..\n";
sleep 60*60;
}
}
答案 2 :(得分:0)
上面对ping谷歌的答案(从2013年开始)具有以下优点:它不依赖于数字来检查互联网连接,因此可以说它更为通用。但是在2019年的典型环境中,只有在连接未启动时对其一部分进行了修改以捕获名称解析错误,该功能才有效。这是在perl中做到这一点的一种方法。在Debian上下文中,可以使用Terminal中的'sudo perl program.pl'启动它。
use warnings;
use strict;
use Net::Ping;
my $p = Net::Ping->new("icmp");
my $netstatus = 1;
eval { $p->ping("www.wikipedia.org"); 1; }
or do { $netstatus = 0; };
if ($netstatus == 1 )
{ printf "Internet connection is active!\n"; }
else
{ printf "Internet connection not active.\n"; }
答案 3 :(得分:0)
我刚才给出的答案,是对Wikipedia的ping操作,需要启动root特权(例如“ sudo”)。为了避免给该程序以root特权,可以通过命令行ping并读取其输出,也可以安装实验性的perl扩展libnet_ping_external,例如在 https://launchpad.net/ubuntu/zesty/amd64/libnet-ping-external-perl/0.13-1 (该页面上的.deb已保存,并且在确认其真实性后,可以打开它进行安装,例如通过文件管理器。) 感谢https://forums.gentoo.org/viewtopic-p-2920594.html的这种方法。这是一个使用此模块的示例(尽管速度较慢),它可以在没有root特权的情况下ping perl。
use warnings;
use strict;
use Net::Ping::External qw(ping);
my $connected = ping(host => "www.google.com");
if ($connected)
{ printf "Internet connection is active!\n"; }
else
{ printf "Internet connection not active.\n"; }