【问题标题】:How to check the presence of the internet connection in Perl?如何在 Perl 中检查 Internet 连接的存在?
【发布时间】:2013-02-14 12:53:02
【问题描述】:

我有一个简单的脚本,它会定期(每隔几秒一次)验证该服务器是否存在互联网连接。需要明确的是,它不会检查外部站点/服务/服务器是否处于活动状态。作为可靠的互联网目的地,我使用 google、yahoo 等网站的 IP。通常我使用 3 个目的地(LAN、ISP 网络、ISP 外部)

我当前负责此的代码只是对ping 的简单而肮脏的调用:

    my $pingResponse = `ping -c 1 -w 1 123.123.123.123`;
    my $isConnected = parsePingResponse($pingResponse);

它似乎有效,但我确信这不是完成这项任务的正确/最佳方式。至少有 3 个缺点:外部系统调用,速度慢,deadline 相对较长,为 1 秒。

所以,我的问题是:如何以 perlish 的方式简单有效地实现 ping 功能,以验证 Internet 连接是否有效?

(我认为 LWP 有点矫枉过正。站点或页面是否可用并不重要,只要可以访问一些外部 IP。可能应该是涉及低级网络的简单事情)

【问题讨论】:

    标签: perl networking connection


    【解决方案1】:

    执行此操作的错误方法是Net::Ping

    my $p = Net::Ping->new;
    if ($p->ping("123.123.123.123", 1)) {
        print "Host is reachable\n";
    }
    

    如果您希望命令运行得更快,超时可能是一个浮点数(例如 0.5)。您需要选择适合您需要的超时时间;较高的超时时间更有可能对 Internet 连接正确,但会花费更长的时间。

    【讨论】:

    • 谢谢,这似乎正是我所需要的。超时和目的地不是问题。还有一个问题,如果你能帮忙解决这个问题:newclose 应该为每个 ping 调用吗? (我的意思是我的脚本几乎 24/7 运行,保持打开的连接不是一个好的行为,可能目标机器会在一段时间后关闭它们;IP 不同,所以我尽量不要 flood 任何人)。
    • 假设您正在执行 TCP ping(默认),您可以在脚本的生命周期内创建一个对象并重复调用 ping。它不会保持打开的连接。
    • 不知道为什么我总是返回 false,但实际上我可以从控制台/终端 ping。
    【解决方案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;
        }   
    }
    

    【讨论】:

    • Docs 说 new() 的 args 有默认值。
    【解决方案3】:

    上面 ping 到 google 的答案(从 2013 年开始)的优点是它不依赖数字来检查 Internet 连接,因此可以说它更通用。但是,在 2019 年的典型环境中,只有在连接未启动时修改其中的某些部分以捕获名称解析错误时,它才会起作用。这是在 perl 中执行此操作的一种方法。在 Debian 上下文中,它可以从终端使用 '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"; }
    

    【讨论】:

      【解决方案4】:

      我刚才给出的答案是 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 权限的情况下在 perl 中 ping 的示例(虽然速度较慢)。

      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"; }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多