perl 检测主机网络模块-Net::Ping
2014-08-10 19:55:41 阿炯

Net::Ping - check a remote host for reachability

用于检测远程主机是否可到达,即常用的ping操作。使用方法示例如下:

use Net::Ping;

#初始该对象
$p = Net::Ping->new();
print "$host is alive.\n" if $p->ping($host);
#关闭该对象
$p->close();
 
$p = Net::Ping->new("icmp");
#绑定是否哪个网口,用于主机有多个网卡的情况
$p->bind($my_addr); # Specify source interface of pings
foreach $host (@host_array){
 print "$host is ";
 print "NOT " unless $p->ping($host, 2);
 print "reachable.\n";
 sleep(1);
}
$p->close();

$p = Net::Ping->new("tcp",2);
#Try connecting to the www port instead of the echo port
#这里对某个服务端口时行测试,即ping服务
$p->port_number(scalar(getservbyname("http", "tcp")));
while ($stop_time > time()){
 print "$host not reachable ", scalar(localtime()), "\n" unless $p->ping($host);
 sleep(300);
}
#关闭释放该对象,同->close方法
undef($p);
 
# Like tcp protocol, but with many hosts
$p = Net::Ping->new("syn");
$p->port_number(getservbyname("http", "tcp"));
foreach $host (@host_array) {
 $p->ping($host);
}
while (($host,$rtt,$ip) = $p->ack) {
 print "HOST: $host [$ip] ACKed in $rtt seconds.\n";
}

#High precision syntax(高精度的时间,可以用于测量所用时间) (requires Time::HiRes)
$p = Net::Ping->new();
$p->hires();
($ret,$duration,$ip) = $p->ping($host,5.5);
 printf("$host [ip: $ip] is alive (packet return time: %.2f ms)\n", 1000 * $duration) if $ret;
$p->close();

#For backward compatibility
print "$host is alive.\n" if pingecho($host);


A ping object is first created with optional parameters, a variable number of hosts may be pinged multiple times and then the connection is closed.

You may choose one of six different protocols to use for the ping. The "tcp" protocol is the default. Note that a live remote host may still fail to be pingable by one or more of these protocols. For example, www.microsoft.com is generally alive but not "icmp" pingable.

可以有六种可选检测协议,是默认的tcp协议。注意远程主机可能无法由一个或多个pingable协议。例如:www.microsoft.com 是一般活着但通过icmp的ping方法是不行的。

tcp

该方式将尝试使用tcp协议与远程主机的echo端口建立连接,如果能成功建立连接则认为它是可到的,实际上并没有数据发送的。这个协议不需要任何特权,但开销高于“udp”和“icmp协议。

udp

该方式将尝试使用udp协议与远程主机的echo端口建立连接,如果能从接收到响应数据包是远程主机和接收到的数据包包含相同的数据则认为它是可到的。这个协议不需要任何特权,它应该记住,如果主机没有适当的echo服务运行,则会认为远程主机是遥不可及的。

icmp

该方式将尝试使用icmp协议向远程主机发送echo消息,unix下的ping大都这么做。如果从远程主机和接收到响应消息响应信息是正确的,则认为远程主机是可到达的。icmp协议要求作为root用户运行程序或为root setuid。

syn

如果使用syn协议,仅发送一个syn包并立即返回,如果包发送成功它将返回一true值,其它则认为远程主机不可到。与其它协议不同的是,它不会使用完整的tcp三次握手,因此它很快。它可以用于快速并行地检测多个目标主机地址,不会对程序造成阻塞,它也不需要任何特殊的权限;但如果远程主机位于防火墙后的话,可能会认为这是攻击行为从而影响检测。

external

可以从Net::Ping::External模块中来进行扩展检测方式。


较新的模块已经支持对端口的探测:
use Net::Ping;

my ($target,$port) = ('192.168.9.85',8090);
my $ping = Net::Ping->new("tcp", 2);
$ping->{'port_num'} = $port;

if($ping->ping($target)){
    print "Yes, I can ping $target:$port\n";
}else{
    print "No, I cannot ping $target:$port\n";
}

$ping->close();


单行版本的ping示例:
perl -MNet::Ping -e '$host="192.168.9.85";if(Net::Ping->new("icmp", 5)->ping("$host",3)){print "$host is alive\n"}'

icmp ping requires root privilege at -e line 1.

部分情况需要在root用户下执行。

一个多协议的ping代码

use Net::Ping;    
$| = 1;
my @hosts = <DATA>;
my @proto = ("tcp", "udp", "icmp", "stream", "syn");
foreach my $pro ( @proto ) {
    print "Protocol $pro \n";
    my $p = Net::Ping->new($pro);
    foreach my $host( @hosts ) {
        chomp($host);
        # Specify source interface of pings
        print "$host is", $p->ping($host, 2)?' ':'Not ', "reachable.\n";
    }
    $p->close();  
}

__DATA__
www.freeoa.net
192.168.9.1
www.perlmonks.com
192.168.7.6

>

Protocol tcp
www.freeoa.net is reachable.
192.168.9.1 is reachable.
www.perlmonks.com is reachable.
192.168.7.6 isNot reachable.
Protocol udp
www.freeoa.net is reachable.
192.168.9.1 is reachable.
www.perlmonks.com is reachable.
192.168.7.6 isNot reachable.
Protocol icmp
icmp ping requires root privilege at pingport3.pl line 7.


最新版本:2.4


项目主页:https://metacpan.org/release/Net-Ping