快捷搜索:   nginx

PHP在线ping域名IP测试通信的几个方法

有时候我们需要使用PHP代码模拟类似DOS的PING命令测试一个域名或者IP的通断情况或者测试域名对应的IP地址及延迟时间,TTL值等数据,这个时候就可以用以下代码来实现

有两种方式,第一种对系统函数要求不大,只要用fsockopen函数就行,第二个要求有exec函数来调用系统的ping,这个被很多虚拟主机给禁用了,因此必须有自己服务器权限,推荐用第一种


<?php
$host = 'www.zzrrr.com';
$port = '80';
$num = 3; //Ping次数
//获取时间
function mt_f (){
list($usec,$sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec); //微秒加秒
}
function ping_f($host,$port){
$time_s = mt_f();
$ip = gethostbyname($host);
$fp = @fsockopen($host,$port);
if(!$fp)
return 'reply time out!';
$get = "GET / HTTP/1.1\r\nHost:".$host."\r\nConnect:".$port."Close\r\n";
fputs($fp,$get);
fclose($fp);
$time_e = mt_f();
$time = $time_e - $time_s;
$time = ceil($time * 1000);
return 'reply from '.$ip.':'.$port.' time = '.$time.'ms<br />';
}
echo 'ping to '.$host.' ['.gethostbyname($host).'] with port:'.$port.' of data:<br />';
for($i = 0;$i < $num;$i++){
echo ping_f($host,$port);
//每次运行中间间隔1S
sleep(1);
//刷新输出缓存
ob_flush();
flush();
}
?>

第二种:用到的是php的内置函数exec来调用系统的ping命令,从而实现ping命令功能的。


<?php
$to_ping='www.zzrrr.com';
$count=2;
$psize=66;
echo "正在执行php ping命令,请等待...\n<br><br>";
flush();
while(1){
 echo "<pre>";
 exec("ping -c $count -s $psize $to_ping", $list);
 for($i=0;$i<count($list);$i++){
  print $list[$i]."\n";
 }
 echo "</pre>";
 flush();
 sleep(3);
}
?>


注意使用exec函数必须需要服务器支持调用系统内置函数才行。另外也可以使用system等php内置函数来实现这个功能。另外需要注意因为在windows和Linux里面PING命令的使用是略有不同的因此最好做个判断

类似这样

<?php
echo 'PHP_INT_MAX : ' . PHP_INT_MAX . "<br><br>";
 
$ip = '115.29.237.28';        // IP地址
 
if (PATH_SEPARATOR==':')    // linux
{
    echo 'I am linux' . "<br><br>";
     
    exec("ping -c 3 -w 5 $ip", $info);
    echo 'linux info : ' . "<br>";
    print_r($info);
     
    $ping_time_line = end($info);
    echo '<br><br>ping_time_line : ' . $ping_time_line . "<br><br>";
     
    $ping_time = explode("=", $ping_time_line)[1];
    $ping_time_min = explode("/", $ping_time)[0] / 1000.0;
    $ping_time_avg = explode("/", $ping_time)[1] / 1000.0;
    $ping_time_max = explode("/", $ping_time)[2] / 1000.0;
     
    echo $ping_time_min . " " . $ping_time_avg . " " . $ping_time_max . "<br><br>";
     
}
else                         // windows
{
    echo 'I am windows' . "<br><br>";
 
    exec("ping -c 3 -w 5 $ip", $info);
    echo 'windows info : ' . "<br>";
    print_r($info);
     
    $info_time = end($info);
    echo '<br><br>info_time : ' . $info_time . "<br><br>";
}
?>

运行结果:

PHP_INT_MAX : 9223372036854775807

I am linux

linux info : 
Array ( [0] => PING 115.29.237.28 (115.29.237.28) 56(84) bytes of data. [1] => 64 bytes from 115.29.237.28: icmp_seq=1 ttl=52 time=26.1 ms [2] => 64 bytes from 115.29.237.28: icmp_seq=2 ttl=52 time=27.5 ms [3] => 64 bytes from 115.29.237.28: icmp_seq=3 ttl=52 time=25.2 ms [4] => [5] => — 115.29.237.28 ping statistics — [6] => 3 packets transmitted, 3 received, 0% packet loss, time 2002ms [7] => rtt min/avg/max/mdev = 25.280/26.339/27.590/0.970 ms ) 

ping_time_line : rtt min/avg/max/mdev = 25.280/26.339/27.590/0.970 ms

0.02528 0.026339 0.02759

如果只需要取延时时间,那就封装成函数

function ping_time($ip) {
    $ping_cmd = "ping -c 3 -w 5 " . $ip;
    exec($ping_cmd, $info);
    $ping_time_line = end($info);
     
    $ping_time = explode("=", $ping_time_line)[1];
    $ping_time_min = explode("/", $ping_time)[0] / 1000.0;
    $ping_time_avg = explode("/", $ping_time)[1] / 1000.0;
    $ping_time_max = explode("/", $ping_time)[2] / 1000.0;
     
    $result = array();
    $result['ping_min'] = $ping_time_min;
    $result['ping_avg'] = $ping_time_avg;
    $result['ping_max'] = $ping_time_max;
     
    print_r($result);
}

 

ping_time('115.29.237.28');

运行结果Array ( [ping_min] => 0.025497 [ping_avg] => 0.025947 [ping_max] => 0.026753 )



附录:

php手册对这exec和system二个函数的解释:

exec --- 执行外部程式

语法 : string exec ( string command [, array &output [, int &return_var]] )

说明 :

exec( )执行给予的命令command,不过它并不会输出任何东西,它简单的从命令的结果中传回最后一行,如果你需要去执行一个命令,并且从命令去取得所有资料时,可以使用passthru( )这个函数。

如果有给予参数array,则指定的数组将会被命令所输出的每一行填满,注意 : 如果数组先前已经包含了一些元素的话,exec( )将会把它附加在数组的后面,如果你不想要此函数附加元素的话,你可以在传递此数组给exec( )之前呼叫unset( )。

如果有给予参数array和return_var,则传回执行的状态命令将会写到这个变量。

意 : 如果你允许来自使用者输入的资料,可以传递到此函数,那么你应该使用escapeshellcmd( )来确定此使用者无法哄骗(trick)系统来执行武断的(arbitrary)命令。

注意 : 如果你使用此函数来启动一个程式,而且希望在背景里(background)执行的时候离开它,你必须确定此程式的输出是转向(redirected)到一个文件或是一些输出的资料流,否则PHP将会悬挂(hang)直到程式执行结束。

system --- 执行外部程式并且显示输出

语法 : string system ( string command [, int &return_var] )

说明 :

system( )执行给予的命令command,并且输出结果。如果有给予参数return_var,则执行命令的状态码将会写到这个变量。

注意 : 如果你允许来自使用者输入的资料,可以传递到此函数,那么你应该使用escapeshellcmd( )来确定此使用者无法哄骗(trick)系统来执行武断的(arbitrary)命令。

注意 : 如果你使用此函数来启动一个程式,而且希望在背景里(background)执行的时候离开它,你必须确定此程式的输出是转向(redirected)到一个文件或是一些输出的资料流,否则PHP将会悬挂(hang)直到程式执行结束。

这二个都是用来调用系统shell命令,不同点:

exec可以把执行的结果全部返回到$output函数里(数组),$status是执行的状态 0为成功 1为失败

systerm不需要提供$output函数,他是直接把结果返回出来,同样$return_var是执行的状态码 0为成功 1为失败


exec示例:


<?php  
$a = exec("dir",$out,$status);  
print_r($a);  
print_r($out);  
print_r($status);  
?>


system示例:


<?php  
$a = system("dir",$out);  
print_r($a);  
print_r($out);  
?>


顶(1)
踩(0)

您可能还会对下面的文章感兴趣:

最新评论