0,'usec'=>500000); $ident = array(ord('J'), ord('C')); $seq = array(rand(0,255), rand(0,255)); ## 8 bytes of ICMP header data $packet = ''; $packet .= chr(8); // type = 8 : request $packet .= chr(0); // code = 0 $packet .= chr(0); // checksum init $packet .= chr(0); // checksum init $packet .= chr($ident[0]); // identifier $packet .= chr($ident[1]); // identifier $packet .= chr($seq[0]); // seq $packet .= chr($seq[1]); // seq for($i=0; $i<$datasize; $i++) $packet .= chr(0); $chk = google::icmpchecksum($packet); $packet[2] = $chk[0]; // checksum init $packet[3] = $chk[1]; // checksum init if(preg_match('/[a-z]/',$host)) $host = gethostbyname($host); // to ip if(!$sock = @socket_create(AF_INET, SOCK_RAW, getprotobyname('icmp'))) { return array(-1, socket_last_error()); } @socket_set_option($sock,SOL_SOCKET,SO_RCVTIMEO,$timeout); // good idea for blocking mode @socket_set_option($sock,SOL_SOCKET,SO_SNDTIMEO,$timeout); $start = microtime(); @socket_sendto($sock, $packet, strlen($packet), 0, $host, $port); $read = array($sock); $write = NULL; $except = NULL; $select = @socket_select($read, $write, $except, 0, 500000); if($select === NULL) { @socket_close($sock); return array(-1,'Select Error'); } else if($select === 0) { @socket_close($sock); return array(-1,'Timeout'); } $recv = ''; @socket_recvfrom($sock, $recv, 65535, 0, $host, $port); $end = microtime(); @socket_close($sock); $recv = unpack('C*', $recv); // ICMP proto = 1 if($recv[10] !== 1) return array(-1,"Not ICMP packet"); // ICMP response = 0 if($recv[21] !== 0) return array(-1,"Not ICMP response"); if($ident[0] !== $recv[25] || $ident[1] !== $recv[26]) return array(-1,"Bad identification number"); if($seq[0] !== $recv[27] || $seq[1] !== $recv[28]) return array(-1,"Bad sequence number"); $rtt = google::getms($start, $end); return array($rtt); } private function &icmpchecksum($data) { $bit = unpack('n*', $data); $sum = array_sum($bit); if (strlen($data) % 2) { $temp = unpack('C*', $data[strlen($data) - 1]); $sum += $temp[1]; } $sum = ($sum >> 16) + ($sum & 0xffff); $sum += ($sum >> 16); return pack('n*', ~$sum); } ## google map loading server latency ## default non-blocking mode ## public function &gethttp($_url, $iporhost='') { static $bsize = 1048576; // socket send/receive buffer size(Bytes) static $timeout = array('sec'=>0,'usec'=>500000); static $port = 80; list($host,$ip,$uri) = google::gethostip($_url,$iporhost); if(!$sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) { return array(-1, socket_last_error()); } @socket_set_option($sock,SOL_SOCKET,SO_SNDBUF,$bsize); @socket_set_option($sock,SOL_SOCKET,SO_RCVBUF,$bsize); @socket_set_option($sock,SOL_SOCKET,SO_RCVTIMEO,$timeout); // good idea for blocking mode @socket_set_option($sock,SOL_SOCKET,SO_SNDTIMEO,$timeout); @socket_set_nonblock($sock); // set to non-blocking mode $req = 'GET '.$uri.' HTTP/1.1'."\r\n". 'Host: '.$host."\r\n". 'User-Agent: PHP/google'."\r\n". 'Connection: close'."\r\n". // good idea for blocking mode "\r\n"; // enf of request header mark $start = microtime(); $code = google::_connect($sock,$ip,$port,5); if($code != 1) { @socket_close($sock); return array(-1, "can not connect to $ip:$port"); } if(!@socket_write($sock,$req)) { @socket_close($sock); return array(-1, "can not send request $uri"); } $header = google::_getheader($sock,1024); // read header $header = google::_parse_header($header); if($header['error']) { @socket_close($sock); return array(-1, $header['status'].' '.$uri); } //$total = $header['content-length']; // total size //$pg = $debug ? $total : 0; // debug mode with progress $size = google::_readsize($sock,$bsize); // check bandwidth mode //google::_readbyall($sock,$buf='',$bsize,$blocking,$pg); //$size = strlen($buf); @socket_close($sock); $end = microtime(); return array(google::getms($start,$end)); } public function gethostip($_url, $iporhost='') { list($nhost,,$uri) = google::_parse_url($_url); if(preg_match('/[a-z]/',$nhost)) $host = $nhost; else $ip = $nhost; if($iporhost) { if(preg_match('/[a-z]/',$iporhost)) $host = $iporhost; else $ip = $iporhost; } if(!$ip) $ip = gethostbyname($host); // to ip else if(!$host) $host = $ip; // not good return array($host,$ip,$uri); } ## connect to host:port ## ## [return] ## 1 or TRUE : connected ## 0 or FALSE : can't connect ## -1 : connetion time out ## private function &_connect(&$sock, $host, $port, $timeout=3) { $_time = time(); while(1) { @socket_connect($sock,$host,$port); if(@socket_last_error()==56 || @socket_last_error()==106) { return TRUE; break; } else if((time()-$_time) >= $timeout) { return -1; break; } } return FALSE; } ## read header by socket_read() ## PHP_NORMAL_READ : 1 ## PHP_BINARY_READ : 2 ## private function &__readheader(&$sock, $bsize) { while($buf = @socket_read($sock,$bsize,PHP_NORMAL_READ)) { //if(!defined('_RESPONSE_END_')) define('_RESPONSE_END_',microtime()); if(!trim($obuf.$buf)) { @socket_read($sock,$bsize,PHP_NORMAL_READ); // seek 1 bytes break; // end of header } $rbuf .= $buf; $obuf = $buf; } return $rbuf; } ## read HTTP all headers ## private function &_getheader(&$sock, $bsize=1024) { $stream = array($sock); while(@socket_select($stream,$write=NULL,$except=NULL,0,500000) !== FALSE) { //if(!in_array($sock,$stream)) break; // is bug ??? $rbuf = google::__readheader($sock,$bsize); break; // require } return $rbuf; } private function &_parse_header($buf) { $lines = preg_split('/[\r\n]+/',trim($buf)); $size = sizeof($lines); $r['status'] = trim($lines[0]); if(!preg_match(';200 OK;',$lines[0])) { $r['error'] = TRUE; return $r; } for($i=1; $i<$size; $i++) { $line = trim($lines[$i]); list($k) = preg_split('/:\s+/',$line); $r[strtolower($k)] = preg_replace(';^'.$k.':\s+;','',$line); } return $r; } ## only read size, this is a bandwidth test version ## private function &_readsize(&$sock, $bsize=1048576) { $stream = array($sock); while(@socket_select($stream,$write=NULL,$except=NULL,0,500000) !== FALSE) { if(!in_array($sock,$stream)) break; if($tsize = strlen(@socket_read($sock,$bsize))) { $rsize += $tsize; } else break; // good idea, EOF } return $rsize; } private function &getms($_start, $_end) { $end = explode(' ', $_end); $start = explode(' ', $_start); return sprintf('%.3f',(($end[1]+$end[0])-($start[1]+$start[0])) * 1000); } private function &_parse_url($_url) { $url = parse_url(preg_replace(';^(?:http://)*;i','http://',trim($_url))); $host = $url['host']; $port = $url['port'] ? $url['port'] : 80; $uri = $url['path'] ? $url['path'] : '/'; if($url['query']) $uri .= '?'.$url['query']; // add san2@2008.12.01 return array($host,$port,$uri); } private function &error($errstr) { return error_log($errstr,0); } } // end of class ?>