内容

名称

Net::Ping - 检查远程主机是否可达

概要

use Net::Ping;

my $p = Net::Ping->new();
print "$host is alive.\n" if $p->ping($host);
$p->close();

my $p = Net::Ping->new("icmp");
$p->bind($my_addr); # Specify source interface of pings
foreach my $host (@host_array)
{
    print "$host is ";
    print "NOT " unless $p->ping($host, 2);
    print "reachable.\n";
    sleep(1);
}
$p->close();

my $p = Net::Ping->new("icmpv6");
my $ip = "[fd00:dead:beef::4e]";
print "$ip is alive.\n" if $p->ping($ip);

my $p = Net::Ping->new("tcp", 2);
# Try connecting to the www port instead of the echo port
$p->port_number(scalar(getservbyname("http", "tcp")));
while ($stop_time > time())
{
    print "$host not reachable ", scalar(localtime()), "\n"
        unless $p->ping($host);
    sleep(300);
}
undef($p);

# Like tcp protocol, but with many hosts
my $p = Net::Ping->new("syn");
$p->port_number(getservbyname("http", "tcp"));
foreach my $host (@host_array) {
  $p->ping($host);
}
while (my ($host, $rtt, $ip) = $p->ack) {
  print "HOST: $host [$ip] ACKed in $rtt seconds.\n";
}

# High precision syntax (requires Time::HiRes)
my $p = Net::Ping->new();
$p->hires();
my ($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);

描述

该模块包含用于测试网络上远程主机可达性的方法。首先使用可选参数创建一个 ping 对象,可以多次 ping 多个主机,然后关闭连接。

您可以选择六种不同的协议用于 ping。默认情况下使用 "tcp" 协议。请注意,活动远程主机可能仍然无法被其中一种或多种协议 ping 通。例如,www.microsoft.com 通常是活动的,但不能被 "icmp" ping 通。

使用 "tcp" 协议,ping() 方法尝试建立与远程主机回声端口的连接。如果连接成功建立,则认为远程主机可达。实际上没有数据被回显。此协议不需要任何特殊权限,但比 "udp" 和 "icmp" 协议开销更高。

指定 "udp" 协议会导致 ping() 方法向远程主机的回声端口发送一个 udp 数据包。如果从远程主机接收到回显数据包,并且接收到的数据包包含与发送的数据包相同的数据,则认为远程主机可达。此协议不需要任何特殊权限。需要注意的是,对于 udp ping,如果主机没有运行相应的回声服务,则会报告主机不可达。对于类 Unix 系统,请参阅 inetd(8) 以获取更多信息。

如果指定 "icmp" 协议,ping() 方法会向远程主机发送一个 icmp 回声消息,这与 UNIX ping 程序所做的事情相同。如果从远程主机接收到回声消息,并且回声信息正确,则认为远程主机可达。指定 "icmp" 协议要求程序以 root 身份运行,或者程序被设置为 root 身份运行。

如果指定了“external”协议,ping() 方法将尝试使用Net::Ping::External模块来 ping 远程主机。Net::Ping::External与您的系统默认的ping工具交互以执行 ping 操作,通常会产生相对准确的结果。如果您的系统上没有安装Net::Ping::External,则指定“external”协议会导致错误。

如果指定了“syn”协议,“ping”方法将只向远程主机发送一个 TCP SYN 数据包,然后立即返回。如果成功发送了 syn 数据包,它将返回一个真值,否则将返回假值。注意:与其他协议不同,返回值并不确定远程主机是否存活,因为完整的 TCP 三次握手可能尚未完成。只有在远程主机在指定超时时间内收到 TCP ACK 时,才认为远程主机是可达的。要开始等待 ACK 数据包,请使用下面解释的“ack”方法。使用“syn”协议而不是“tcp”协议来确定通过发送并行的 TCP SYN 数据包来同时到达多个目的地的可达性。它在测试每个远程主机时不会阻塞。此协议不需要任何特殊权限。

函数

Net::Ping->new([proto, timeout, bytes, device, tos, ttl, family, host, port, bind, gateway, retrans, pingstring, source_verify econnrefused dontfrag IPV6_USE_MIN_MTU IPV6_RECVPATHMTU])

创建一个新的 ping 对象。所有参数都是可选的,可以作为哈希引用传递。除了前 7 个选项之外,所有选项都必须作为哈希引用传递。

proto指定在执行 ping 操作时使用的协议。当前选项是“tcp”、“udp”、“icmp”、“icmpv6”、“stream”、“syn”或“external”。默认值为“tcp”。

如果提供了以秒为单位的timeout,则在 ping() 方法(如下)未给出超时时间时使用它。超时时间必须大于 0,默认值为 5 秒(如果未指定)。

如果给出了数据字节数 (bytes),则将这些数据字节包含在发送到远程主机的 ping 数据包中。如果协议为“tcp”,则忽略数据字节数。如果协议为“udp”,则最小(也是默认)数据字节数为 1,否则为 0。可以指定的最大数据字节数为 65535,但建议保持在 MTU(ICMP 为 1472 字节)以下。许多小型设备无法处理分段的 ICMP 数据包。

如果给出了device,则此设备用于在发送 ping 数据包之前绑定源端点。我相信这目前仅适用于超级用户权限以及 udp 和 icmp 协议。

如果给出了<tos>,则将此 ToS 配置到套接字中。

对于 icmp,ttl 可以指定为设置传出数据包的 TTL。

IPv4 的有效 family

4, v4, ip4, ipv4, AF_INET (constant)

IPv6 的有效 family

6, v6, ip6, ipv6, AF_INET6 (constant)

如果未给出 family 参数,则 host 参数隐式指定 family。

port 参数仅对 udp、tcp 或 stream ping 有效,并且不会按预期执行。当我们收到“连接被拒绝”时,ping 返回 true!默认值为回显端口。

bind 参数指定要绑定的 local_addr。通过指定 bind 参数,您不需要 bind 方法。

gateway 参数仅对 IPv6 有效,并且需要 IPv6 地址。

retrans 参数为指数退避率,默认值为 1.2。它与 $def_factor 全局变量匹配。

dontfrag 参数设置 IP_DONTFRAG 位,但请注意,IP_DONTFRAG 尚未由 Socket 定义,并且在许多系统上不可用。然后它被忽略。在 Linux 上,它还将 IP_MTU_DISCOVER 设置为 IP_PMTUDISC_DO,但我们需要不分割超大数据包。您需要手动设置 $data_size。

$p->ping($host [, $timeout [, $family]]);

ping 远程主机并等待响应。$host 可以是远程主机的 hostname 或 IP 号码。可选的 timeout 必须大于 0 秒,默认值为创建 ping 对象时指定的任何值。返回成功标志。如果找不到 hostname 或 IP 号码存在问题,则返回的成功标志将为 undef。否则,如果主机可达,则成功标志将为 1,如果不可达,则为 0。对于大多数实际目的,undef 和 0 可以被视为相同的情况。在数组上下文中,还返回经过的时间以及主机解析到的 ip 的字符串形式。如果之前调用了 hires(),则经过的时间值将是一个浮点数,如 Time::HiRes::time() 函数返回的那样,否则它将作为整数返回。

$p->source_verify( { 0 | 1 } );

允许启用或禁用源端点验证。这对于那些具有多个接口的远程目标很有用,因为响应可能不是来自发送原始目标端点的同一端点。这仅影响 udp 和 icmp 协议 ping。

默认情况下启用此功能。

$p->service_check( { 0 | 1 } );

设置连接行为是否应该强制执行远程服务可用性以及可达性。通常,如果远程服务器报告 ECONNREFUSED,则它一定是可达的,因为它是通过它报告的状态包来确定的。启用此选项后,必须成功建立完整的 TCP 三次握手,然后才能声明它可达。注意:它仍然只执行连接和断开连接操作。它不会使用任何协议(例如 HTTP 或 FTP)来确保远程服务器在任何方面都是正常的。远程服务器 CPU 可能正在不断运行并对任何连接的客户端无响应,但如果内核抛出 ACK 包,则无论如何它都被认为是活动的。要真正确定服务器是否响应良好,则需要特定于应用程序,并且超出了 Net::Ping 的范围。对于 udp 协议,启用此选项要求远程服务器使用与 udp 回声服务定义的相同 udp 数据进行回复。

这会影响 "udp"、"tcp" 和 "syn" 协议。

默认情况下禁用此功能。

$p->tcp_service_check( { 0 | 1 } );

已弃用方法,但与 service_check() 方法相同。

$p->hires( { 0 | 1 } );

使用 1 会导致此模块使用 Time::HiRes 模块,允许后续对 ping() 的调用返回毫秒。

$p->time

当前时间,无论是否使用 hires。

$p->socket_blocking_mode( $fh, $mode );

在文件句柄上设置或清除 O_NONBLOCK 标志。

$p->IPV6_USE_MIN_MTU

使用参数设置选项。不带参数则返回选项值。

$p->IPV6_RECVPATHMTU

通知相应的 IPv6 MTU。

使用参数设置选项。不带参数则返回选项值。

$p->IPV6_HOPLIMIT

使用参数设置选项。不带参数则返回选项值。

$p->IPV6_REACHCONF NYI

设置 IPv6 可达性 IPV6_REACHCONF 在 RFC3542 中被移除。ping6 -R 支持它。IPV6_REACHCONF 需要 root/管理员权限。

使用参数设置选项。不带参数则返回选项值。

尚未实现。

$p->bind($local_addr);

设置发送 ping 的源地址。这必须是本地主机上的某个接口的地址。$local_addr 可以指定为主机名或文本 IP 地址,例如“192.168.1.1”。

如果协议设置为“tcp”,则此方法可以调用任意次数,并且每次调用 ping() 方法(如下)都将使用最新的 $local_addr。如果协议是“icmp”或“udp”,则 bind() 每个对象最多只能调用一次,并且(如果调用了)必须在对该对象的第一个 ping() 调用之前调用。

在为 new() 指定 bind 选项时,可以省略 bind() 调用。

$p->message_type([$ping_type]);

当您使用“icmp”协议时,此调用允许您将消息类型更改为“echo”或“timestamp”(仅适用于 IPv4,请参阅 RFC 792)。

没有参数,它将返回当前使用的 icmp 协议消息类型。默认情况下,它返回“echo”。

$p->open($host);

当您使用“stream”协议时,此调用会预先打开 tcp 套接字。只有在您想要在创建连接时提供不同的超时,或者从第一个 ping 中删除建立连接的开销时,才需要这样做。如果您不调用 open(),则连接会在第一次调用 ping() 时自动打开。如果您使用除 stream 以外的任何协议,此调用将什么也不做。

在为 new() 指定 host 选项时,可以省略 $host 参数。

$p->ack( [ $host ] );

当使用 "syn" 协议时,使用此方法确定远程主机的可达性。此方法旨在调用次数与 ping() 调用次数相同。每次调用都返回带有 TCP ACK 的主机(如传递给 ping())。主机返回的顺序不一定与使用 ping() 方法进行 SYN 排队的顺序相同。如果在收到 TCP ACK 之前达到超时,或者远程主机未监听尝试的端口,则 TCP 连接将无法建立,ack() 将返回 undef。在列表上下文中,将返回主机、ack 时间、点分十进制 IP 字符串和端口号,而不是仅返回主机。如果指定了可选的 $host 参数,则返回值将仅与该主机相关。如果您使用除 "syn" 之外的任何协议,则此调用什么也不做。

"new" 具有主机选项时,将使用此主机。如果没有 $host 参数,则会扫描所有主机。

$p->nack( $failed_ack_host );

host $failed_ack_host 未收到有效 ACK 的原因。当 ack($fail_ack_host) 返回假值时,此方法有助于找出原因。

$p->ack_unfork($host)

使用 "syn" 协议和启用 $syn_forking 时,由 "ack" 调用的变体。

$p->ping_icmp([$host, $timeout, $family])

使用 icmp 协议的 "ping" 方法。

$p->ping_icmpv6([$host, $timeout, $family])

使用 icmpv6 协议的 "ping" 方法。

$p->ping_stream([$host, $timeout, $family])

使用 stream 协议的 "ping" 方法。

执行流 ping 操作。如果 TCP 连接尚未打开,则打开它。然后发送一些数据并等待回复。退出时保持流打开。

$p->ping_syn([$host, $ip, $start_time, $stop_time])

使用 syn 协议的 "ping" 方法。向指定主机发送 TCP SYN 数据包。

$p->ping_syn_fork([$host, $timeout, $family])

使用 fork syn 协议的 "ping" 方法。

$p->ping_tcp([$host, $timeout, $family])

使用 tcp 协议的 "ping" 方法。

$p->ping_udp([$host, $timeout, $family])

使用 udp 协议的 "ping" 方法。

执行 udp 回声 ping 操作。构建一个至少包含一个字节序列号和任何其他数据字节的消息。发送消息并等待消息返回。如果收到消息,请确保其所有部分都匹配。如果匹配,则完成。否则,返回并等待消息,直到超时。返回我们努力的结果。

$p->ping_external([$host, $timeout, $family])

使用外部协议的 "ping" 方法。使用 Net::Ping::External 执行外部 ping 操作。

$p->tcp_connect([$ip, $timeout])

启动 TCP 连接,用于 tcp ping 操作。

$p->tcp_echo([$ip, $timeout, $pingstring])

执行 TCP 回声操作。它将给定字符串写入套接字,然后将其读回。成功时返回 1,失败时返回 0。

$p->close();

关闭此 ping 对象的网络连接。网络连接也会被“undef $p”关闭。如果 ping 对象超出范围(例如,$p 是子例程的局部变量,并且您离开了子例程),则网络连接会自动关闭。

$p->port_number([$port_number])

当使用端口号调用时,用于 ping 的端口号将设置为 $port_number,而不是使用回显端口。它还具有调用 $p->service_check(1) 的效果,导致 ping 仅在该特定端口可访问时返回成功响应。此函数返回 "ping" 将连接到的端口的值。

$p->mselect

一个 select() 包装器,用于补偿平台的特殊性。

$p->ntop

inet_ntop() 的平台抽象。

$p->checksum($msg)

对消息进行校验和。基本上将所有短字相加,并将高位折叠到低位。

$p->icmp_result

返回一个 addr、type、subcode 列表。

pingecho($host [, $timeout]);

为了提供与 Net::Ping 的先前版本向后兼容性,提供了一个 pingecho() 子例程,其功能与以前相同。pingecho() 使用 tcp 协议。返回值和参数与 "ping" 方法中描述的相同。此子例程已过时,可能会在 Net::Ping 的未来版本中删除。

wakeonlan($mac, [$host, [$port]])

发出流行的唤醒网络 (WOL) 魔术 udp 数据包以唤醒本地设备。另请参见 Net::Wake,但此方法将 mac 地址作为第一个参数。$host 应该是本地网关。如果没有,将广播。

默认主机:'255.255.255.255' 默认端口:9

perl -MNet::Ping=wakeonlan -e'wakeonlan "e0:69:95:35:68:d2"'

注释

如果您指定 udp 或 icmp 协议,网络开销将更少(并且程序效率更高)。对于每次 ping,tcp 协议将生成比 udp 或 icmp 多 2.5 倍或更多的流量。如果频繁 ping 许多主机,您可能希望在每次 ping 之间实现一个小的等待时间(例如 25 毫秒或更长),以避免用数据包淹没您的网络。

icmp 和 icmpv6 协议要求程序以 root 身份运行,或将其设置为 root 权限。其他协议不需要特殊权限,但并非所有网络设备都实现 tcp 或 udp echo。

本地主机通常应该在几毫秒内响应 ping。但是,在非常拥挤的网络上,从远程主机接收回声数据包可能需要长达 3 秒或更长时间。如果在这种情况下将超时设置得太低,则远程主机似乎不可达(这几乎是事实)。

可达性并不一定意味着远程主机实际上除了回声数据包之外还能正常运行。tcp 比 icmp 更能指示系统的健康状况,因为它使用更多网络堆栈来响应。

由于缺乏更好的方法,此模块使用自己的例程来打包和解包 ICMP 数据包。最好编写一个单独的模块来理解所有不同类型的 ICMP 数据包。

安装

最新的源代码树可以通过 git 获取

git clone https://github.com/rurban/Net-Ping.git
cd Net-Ping

可以按如下方式创建 tarball

perl Makefile.PL ; make ; make dist

最新的 Net::Ping 版本包含在 cperl 和 perl5 中。

错误

有关已知问题的列表,请访问

https://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-Pinghttps://github.com/rurban/Net-Ping/issues

要报告新的错误,请访问

https://github.com/rurban/Net-Ping/issues

作者

Current maintainers:
  perl11 (for cperl, with IPv6 support and more)
  p5p    (for perl5)

Previous maintainers:
  [email protected] (Rob Brown)
  Steve Peters

External protocol:
  [email protected] (Colin McMillen)

Stream protocol:
  [email protected] (Scott Bronson)

Wake-on-lan:
  1999-2003 Clinton Wong

Original pingecho():
  [email protected] (Andreas Karrer)
  [email protected] (Paul Marquess)

Original Net::Ping author:
  [email protected] (Russell Mosemann)

版权

版权所有 (c) 2017-2020,Reini Urban。保留所有权利。

版权所有 (c) 2016,cPanel Inc. 保留所有权利。

版权所有 (c) 2012,Steve Peters。保留所有权利。

版权所有 (c) 2002-2003,Rob Brown。保留所有权利。

版权所有 (c) 2001,Colin McMillen。保留所有权利。

本程序是自由软件;您可以根据与 Perl 本身相同的条款重新分发它和/或修改它。