php通过类方法实现ping功能

//通过在URL中输入域名,ping的次数例如 :http://localhost:8080/demo2/ping.php?domain=www.google.com&num=3


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>php实现ping功能</title>
</head>

<body>
<?php

class CNetPing
{
    public  $icmp_socket;

    public $request;
   // public $request_len;
   // var $reply;
    public $errstr;
  //  public $time;  //建立连接到发送包得到响应的时间
    public $timer_start_time; //开始发送请求包的时间
    public $lost_package=0;//默认丢失的包的数量为0
    public $recv_package=0;//默认接受到的包的数量为0
    public $times=array();

    function CNetPing()
    {
        $this->icmp_socket = socket_create(AF_INET, SOCK_RAW, 1);
        //echo "  $this->icmp_socket";
        socket_set_block($this->icmp_socket);

    }


//如果调用时不带可选参数,本函数以 "msec sec" 的格式返回一个字符串,其中 sec 是自 Unix 纪元(0:00:00 January 1, 1970 GMT)起到现在的秒数,msec 是微秒部分。
//字符串的两部分都是以秒为单位返回的

    function start_time()
    {
        $this->timer_start_time = microtime();//microtime() 函数返回当前 Unix 时间戳和微秒数。

        //echo "$this->timer_start_time";
    }

    function get_time($percision = 2)
    {

        // format start time
        list($start_usec, $start_sec) = explode(" ", $this->timer_start_time);//explode() 函数把字符串分割为数组
        $start_time = ((float)$start_usec + (float)$start_sec);

        // get and format end time
        list($end_usec, $end_sec) = explode(" ", microtime());
        $end_time = ((float)$end_usec + (float)$end_sec);

        $total_time = $end_time - $start_time;

        return number_format(1000*$total_time, $percision);
    }




    /**
     * @param $dst_addr
     * @param int $timeout
     * @param int $percision
     * @return bool|string
     */

    function ping($dst_addr,$num, $timeout = 5, $percision = 3)
    {

        // lets catch dumb people
        if ((int)$timeout <= 0) $timeout = 5;
        if ((int)$percision <= 0) $percision = 3;

        /* create the socket, the last '1' denotes ICMP */
       // $socket = socket_create(AF_INET, SOCK_RAW, 1);

        /* set socket receive timeout to 1 second */
        //socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => $timeout, "usec" => 0));
        for($i=0;$i<$num;$i++) {
            socket_set_option($this->icmp_socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => $timeout, "usec" => 0));

            /* connect to socket */
            if (socket_connect($this->icmp_socket, $dst_addr, null)) {
                echo "socket_connect连接 $dst_addr.成功<br>";
            } else {
                $this->errstr = "Cannot connect to $dst_addr";
                return FALSE;
            }

            /* 创建一个发送包*/

            $this->request = "\x08\x00\x19\x2f\x00\x00\x00\x00\x70\x69\x6e\x67";
            /* record start time */
            $this->start_time();

            socket_send($this->icmp_socket, $this->request, strlen($this->request), 0);
            //socket_send($this->icmp_socket,$package,strlen($package),0);

            if (@socket_read($this->icmp_socket, 255)) {

                //$this->time = $this->get_time($percision);
               $this->times[$i]=$this->get_time($percision);
                $this->recv_package++;
                //return $this->time;

            } else {
                $this->lost_package++;
                $this->errstr = "Timed out";
            }

            socket_close(icmp_socket);
        }
    }
}


    $domain=$_GET['domain'];
    $num=$_GET['num'];
    echo "域名:".$domain."<br>";
    echo "次数:".$num."<br>";
    $percision=3;
    $address = gethostbyname($domain);

    $ping=new CNetPing();
    $ping->ping($address, $num, $percision);
    echo"已接受的数据包个数为:$ping->recv_package<br>";
    echo"丢失的数据包个数为:$ping->lost_package<br>";
    if($ping->recv_package==0){
        echo "$ping->errstr";
    }else{

        sort($ping->times);//系统排序函数。升序函数(从小到大排序)

        echo "最短时间为:".$ping->times[0]."ms      最长时间为:".$ping->times[$num-1]."ms  平均时间为:"
            .number_format((array_sum($ping->times)/$num),$percision)."ms<br>";//array_sum()计算数组中所有值的和
    }

?>
</body>
</html>

 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
您好!您的问题是如何使用 PHP Socket 实现 ping 功能实现 ping 功能可以通过发送 ICMP 报文来模拟网络 ping 操作。但是,由于 ICMP 协议是一个底层协议,PHP Socket 并不直接支持 ICMP,因此您需要使用原始套接字来发送 ICMP 报文。 以下是一个基本的 PHP Socket 实现 ping 功能的示例: ```php <?php $host = 'example.com'; $port = 80; // ping 80端口 $socket = socket_create(AF_INET, SOCK_RAW, 1); // 创建原始套接字 if ($socket === false) { echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; exit; } socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 1, 'usec' => 0)); // 设置超时时间为1秒 $startTime = microtime(true); $packet = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost"; // 构造 ICMP 报文 $socket_sendto($socket, $packet, strlen($packet), 0, $host, 0); // 发送 ICMP 报文 if (socket_read($socket, 255)) { // 接收 ICMP 响应报文 $endTime = microtime(true); $timeElapsed = ($endTime - $startTime) * 1000; echo "Ping took $timeElapsed ms"; } else { echo "Ping timed out"; } socket_close($socket); // 关闭套接字 ``` 需要注意的是,由于 ICMP 协议需要特殊的权限才能发送和接收 ICMP 报文,因此您需要以 root 用户或管理员身份运行该脚本。同时,该示例中使用了 80 端口来 ping 目标主机,但实际上 ping 操作并不需要使用端口,这只是为了方便演示而添加的。 希望这个示例对您有所帮助!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值