欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

PHP ping

程序员文章站 2022-03-18 14:33:04
使用方法: ......
  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
}