PHP ping

2018-09-19 02:56:03来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

  1 <?php
  2 /// start ping.inc.php ///
  3 
  4 $g_icmp_error = "No Error";
  5 
  6 // timeout in ms
  7 function ping($host, $timeout)
  8 {
  9     $port = 0;
 10     $datasize = 64;
 11     global $g_icmp_error;
 12     $g_icmp_error = "No Error";
 13     $ident = array(ord('J'), ord('C'));
 14     $seq = array(rand(0, 255), rand(0, 255));
 15 
 16     $packet = '';
 17     $packet .= chr(8); // type = 8 : request
 18     $packet .= chr(0); // code = 0
 19 
 20     $packet .= chr(0); // checksum init
 21     $packet .= chr(0); // checksum init
 22 
 23     $packet .= chr($ident[0]); // identifier
 24     $packet .= chr($ident[1]); // identifier
 25 
 26     $packet .= chr($seq[0]); // seq
 27     $packet .= chr($seq[1]); // seq
 28 
 29     for ($i = 0; $i < $datasize; $i++)
 30         $packet .= chr(0);
 31 
 32     $chk = icmpChecksum($packet);
 33 
 34     $packet[2] = $chk[0]; // checksum init
 35     $packet[3] = $chk[1]; // checksum init
 36 
 37     $sock = socket_create(AF_INET, SOCK_RAW, getprotobyname('icmp'));
 38     $time_start = microtime(true);
 39     socket_sendto($sock, $packet, strlen($packet), 0, $host, $port);
 40 
 41 
 42     $read = array($sock);
 43     $write = NULL;
 44     $except = NULL;
 45 
 46     $select = socket_select($read, $write, $except, 0, $timeout * 1000);
 47     if ($select === NULL) {
 48         $g_icmp_error = "Select Error";
 49         socket_close($sock);
 50         return -1;
 51     } elseif ($select === 0) {
 52         $g_icmp_error = "Timeout";
 53         socket_close($sock);
 54         return -1;
 55     }
 56 
 57     $recv = '';
 58     $time_stop = microtime(true);
 59     socket_recvfrom($sock, $recv, 65535, 0, $host, $port);
 60     $recv = unpack('C*', $recv);
 61 
 62     if ($recv[10] !== 1) // ICMP proto = 1
 63     {
 64         $g_icmp_error = "Not ICMP packet";
 65         socket_close($sock);
 66         return -1;
 67     }
 68 
 69     if ($recv[21] !== 0) // ICMP response = 0
 70     {
 71         $g_icmp_error = "Not ICMP response";
 72         socket_close($sock);
 73         return -1;
 74     }
 75 
 76     if ($ident[0] !== $recv[25] || $ident[1] !== $recv[26]) {
 77         $g_icmp_error = "Bad identification number";
 78         socket_close($sock);
 79         return -1;
 80     }
 81 
 82     if ($seq[0] !== $recv[27] || $seq[1] !== $recv[28]) {
 83         $g_icmp_error = "Bad sequence number";
 84         socket_close($sock);
 85         return -1;
 86     }
 87 
 88     $ms = bcmul(bcsub($time_stop, $time_start, 6), 1000);
 89 
 90     if ($ms < 0) {
 91         $g_icmp_error = "Response too long";
 92         $ms = -1;
 93     }
 94 
 95     socket_close($sock);
 96 
 97     return $ms;
 98 }
 99 
100 function icmpChecksum($data)
101 {
102     $bit = unpack('n*', $data);
103     $sum = array_sum($bit);
104 
105     if (strlen($data) % 2) {
106         $temp = unpack('C*', $data[strlen($data) - 1]);
107         $sum += $temp[1];
108     }
109 
110     $sum = ($sum >> 16) + ($sum & 0xffff);
111     $sum += ($sum >> 16);
112 
113     return pack('n*', ~$sum);
114 }
115 
116 function getLastIcmpError()
117 {
118     global $g_icmp_error;
119     return $g_icmp_error;
120 }
121 /// end ping.inc.php ///

使用方法: 

$ping = ping('www.baidu.com',200);
if ($ping > 0) {
    // ok  
} else {
    // failed
}

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:linux下LAMP环境下部署php网站

下一篇:MySQL多表联查之ThinkPHP中的实现