+ -
当前位置:首页 → 问答吧 → [SOCKET] PHP 中如何使用ICMP?

[SOCKET] PHP 中如何使用ICMP?

时间:2005-12-03

来源:互联网

只知道用socket_create创建一个,用socket_connect尝试连接。

使用TCP的80可以了,但是使用ICMP的方法却不会。

在php.net上看了手册了没有找到,朋友们帮忙呀。

作者: 78020281   发布时间: 2005-12-03

只能exec("ping")吧

作者: 笨狗   发布时间: 2005-12-03

http://www.php.net/manual/zh/ref.sockets.php

[Copy to clipboard] [ - ]
CODE:
<?php

class Net_Ping
{
  var $icmp_socket;
  var $request;
  var $request_len;
  var $reply;
  var $errstr;
  var $time;
  var $timer_start_time;
  function Net_Ping()
  {
   $this->icmp_socket = socket_create(AF_INET, SOCK_RAW, 1);
   socket_set_block($this->icmp_socket);
  }

  function ip_checksum($data)
  {
     for($i=0;$i<strlen($data);$i += 2)
     {
         if($data[$i+1]) $bits = unpack('n*',$data[$i].$data[$i+1]);
         else $bits = unpack('C*',$data[$i]);
         $sum += $bits[1];
     }
   
     while ($sum>>16) $sum = ($sum & 0xffff) + ($sum >> 16);
     $checksum = pack('n1',~$sum);
     return $checksum;
  }

  function start_time()
  {
   $this->timer_start_time = microtime();
  }

  function get_time($acc=2)
  {
   // format start time
   $start_time = explode (" ", $this->timer_start_time);
   $start_time = $start_time[1] + $start_time[0];
   // get and format end time
   $end_time = explode (" ", microtime());
   $end_time = $end_time[1] + $end_time[0];
   return number_format ($end_time - $start_time, $acc);
  }

  function Build_Packet()
  {
   $data = "abcdefghijklmnopqrstuvwabcdefghi"; // the actual test data
   $type = "\x08"; // 8 echo message; 0 echo reply message
   $code = "\x00"; // always 0 for this program
   $chksm = "\x00\x00"; // generate checksum for icmp request
   $id = "\x00\x00"; // we will have to work with this later
   $sqn = "\x00\x00"; // we will have to work with this later

   // now we need to change the checksum to the real checksum
   $chksm = $this->ip_checksum($type.$code.$chksm.$id.$sqn.$data);

   // now lets build the actual icmp packet
   $this->request = $type.$code.$chksm.$id.$sqn.$data;
   $this->request_len = strlen($this->request);
  }

  function Ping($dst_addr,$timeout=5,$percision=3)
  {
   // lets catch dumb people
   if ((int)$timeout <= 0) $timeout=5;
   if ((int)$percision <= 0) $percision=3;
  
   // set the timeout
   socket_set_option($this->icmp_socket,
     SOL_SOCKET,  // socket level
     SO_RCVTIMEO, // timeout option
     array(
       "sec"=>$timeout, // Timeout in seconds
       "usec"=>0  // I assume timeout in microseconds
       )
     );

   if ($dst_addr)
   {
     if (@socket_connect($this->icmp_socket, $dst_addr, NULL))
     {
   
     } else {
       $this->errstr = "Cannot connect to $dst_addr";
       return FALSE;
     }
     $this->Build_Packet();
     $this->start_time();
     socket_write($this->icmp_socket, $this->request, $this->request_len);
     if (@socket_recv($this->icmp_socket, &$this->reply, 256, 0))
     {
       $this->time = $this->get_time($percision);
       return $this->time;
     } else {
       $this->errstr = "Timed out";
       return FALSE;
     }
   } else {
     $this->errstr = "Destination address not specified";
     return FALSE;
   }
  }
}

$ping = new Net_Ping;
$ping->ping("www.google.ca");

if ($ping->time)
  echo "Time: ".$ping->time;
else
  echo $ping->errstr;

?>

作者: HonestQiao   发布时间: 2005-12-03

版主的方法我试过了。
有错误报告:
[function.socket-create]: Unable to create socket [0]: 以一种访问权限不允许的方式做了一个访问套接字的尝试。


CU没有人做过这事吗?

作者: 78020281   发布时间: 2005-12-05



QUOTE:
原帖由 78020281 于 2005-12-5 09:25 发表
版主的方法我试过了。
有错误报告:
[function.socket-create]: Unable to create socket [0]: 以一种访问权限不允许的方式做了一个访问套接字的尝试。


CU没有人做过这事吗?

我在Windows测试都可以的啊。

你在最开头加上error_reporting(E_ALL);

记住,如果是windows,需要在php.ini把socket的dll打开的哦。

作者: HonestQiao   发布时间: 2005-12-05

我是直接复制过去运行的,不知道行不行?


sockets.dll 是打开的。

作者: 78020281   发布时间: 2005-12-05



QUOTE:
原帖由 78020281 于 2005-12-5 15:50 发表
我是直接复制过去运行的,不知道行不行?


sockets.dll 是打开的。

我一开始也是出现立的错误。

后来我加了最开投的那句话,看到了错误提示说不支持,我就打开socket,他就好了的。

作者: HonestQiao   发布时间: 2005-12-05

我试上面代码.

php.ini中已经 sockets.use_system_read = On

执行页面时出现错误提示:
Warning: socket_create() Unable to create socket [1]: Operation not permitted in /www/test/Net_Ping.php on line 14

Warning: socket_set_block() expects parameter 1 to be resource, boolean given in /www/test/Net_Ping.php on line 15

Warning: socket_set_option() expects parameter 1 to be resource, boolean given in /www/test/Net_Ping.php on line 79
Cannot connect to www.google.com

作者: Qlin   发布时间: 2005-12-07

呵呵, 因为 SOCKET_RAW 也就是原始套接字必须 root 才能建立的.

所以 web 运行的话并不一定是 root (管理员权限), 版主可能是在 cli 模式下测试

作者: hightman   发布时间: 2005-12-07

如果我不提升web的权限有没有办法解决这个问题 .?

作者: Qlin   发布时间: 2005-12-07



QUOTE:
原帖由 Qlin 于 2005-12-7 16:23 发表
如果我不提升web的权限有没有办法解决这个问题 .?

是的, 如果主机是 Unix-Like OS 那么没有办法的 除非你的 php是以  CGI  方式运行,那么可能也就可以用 setuid() 来操作

如果是 windows 的主机, 那么可能没有这么严格应该就可以

作者: hightman   发布时间: 2005-12-07

谢谢hightman兄.

作者: Qlin   发布时间: 2005-12-07

热门下载

更多