【问题标题】:PHP: How can I ping an IP address fasterPHP:如何更快地 ping IP 地址
【发布时间】:2018-01-14 11:21:18
【问题描述】:

我正在使用 exec("ping " . $server->ip, $output, $result);功能,我正在尝试 ping 几个 IP 地址,并且需要花费太多时间来逐个 ping 它们。有没有更快的方法来 ping 它们。

    //In my controller
    $servers = Server::orderBy('created_at', 'desc')->paginate(10);

    foreach ($servers as $server)
    {
        exec("ping " . $server->ip, $output, $result);

        if($result != 0)
        {
          $server->status = 0;
        }
        else
        {
          $server->status = 1;
        }

    }

【问题讨论】:

标签: php networking server monitoring ping


【解决方案1】:

所以这里有两种方法:

  1. 使用批处理文件
  2. 使用fsockopen()函数

1。使用批处理文件:

为什么要使用它,因为每次调用exec函数时大部分时间都花在创建shell上,所以想法是创建一个小程序,在命令行循环你的IP地址,只需调用一次system PHP 命令,这就是您需要做的事情以及之后的解释。 - 在您的 doucment_root 目录中创建一个批处理文件batch.bat,将以下命令输入其中:

set list=172.30.240.56 172.30.240.57 172.30.240.58
(for %%a in (%list%) do ( 
   ping -n 1 %%a 
));

您可以使用由空格分隔的 IP 地址填写上面的列表。 ping -n 1 只 ping 一次,因为你需要速度

Then in your script, it will be as simple as putting:
echo '<pre>';
exec('cmd /c .\batch.bat',$result);
/* $result is an array of lines of the output that you can easily access
look at the result obtained by using print_r($result); below

您甚至可以在 PHP 脚本中自动创建批处理文件,前提是您具有正确的权限(您可能会喜欢它,因为您可以运行 exec),方法是键入:

$servers = Server::orderBy('created_at', 'desc')->paginate(10);
$batch_string=' set list=';
foreach ($servers as $server)
    $batch_string.=$server->ip.' ';
$batch_string.= "\n (for %%a in (%list%) do ( 
    ping -n 1 %%a 
));";
file_put_contents('batch.bat',$batch_string);
echo '<pre>';
exec('cmd /c .\batch.bat',$result);

我用www.google.com172.30.240.56 对此进行了测试,结果如下: (请注意,对于第二个 IP 地址,ping 失败)

Array
(
    [0] => 
    [1] => C:\Batch_File_path>set list=www.google.com 172.30.240.56
    [2] => 
    [3] => C:\Batch_File_path>(for %a in (www.google.com 172.30.240.56) do (ping -n 1 %a  ) )
    [4] => 
    [5] => C:\Batch_File_path>(ping -n 1 www.google.com  )
    [6] => 
    [7] => Pinging www.google.com [172.217.23.196] with 32 bytes of data:
    [8] => Reply from 172.217.23.196: bytes=32 time=84ms TTL=48
    [9] => 
    [10] => Ping statistics for 172.217.23.196:
    [11] =>     Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
    [12] => Approximate round trip times in milli-seconds:
    [13] =>     Minimum = 84ms, Maximum = 84ms, Average = 84ms
    [14] => 
    [15] => C:\Batch_File_path>(ping -n 1 172.30.240.56  )
    [16] => 
    [17] => Pinging 172.30.240.56 with 32 bytes of data:
    [18] => Request timed out.
    [19] => 
    [20] => Ping statistics for 172.30.240.56:
    [21] =>     Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
)

2。使用fsockopen 命令:

使用套接字,它是PHP内置的,因此维护和检测错误更快更容易,这里是一个ping Ip地址的示例代码

$fp = fsockopen("www.google.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.google.com\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}

【讨论】:

  • 我尝试使用 fsock 功能,但我之前的一些在线 IP 地址已离线
  • @GrantGubatan,您是否检查以确保该端口没有被防火墙/iptables 阻止
  • 我应该如何以及在哪里检查它?
  • @GrantGubatan,尝试使用端口 80 php.net/manual/en/function.fsockopen.php 的默认示例,看看是否可能是端口阻塞问题
  • @GrantGubatan,我已经更新了代码,经过测试的代码运行良好,请尝试使用完全相同的代码并告诉我发生了什么
猜你喜欢
  • 2013-09-08
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 2013-06-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多