很就没更新博客了。今天更新一篇文章,今天要讲的是TLV格式和TLV在PHP5中的应用。

       讲到TLV格式可能很多人都没有听说过吧。不过不要紧,今天我们就一直来了解它。

TLV是一种可变格式,主要用到在客服端与服务端之间的数据发送。说道其本质是是客服端向服务段数据传输双方规定的一个协议。

 

TLV中T、L字段的长度往往固定(通常为1~4bytes),V字段长度可变。顾名思义,T字段表示数值类型,L字段表示数值长度、V字段往往用来存放数值。

 

T:Tag标识,用于标识该数据元,类似于数组中的key

L:Length长度,TLV中Value的长度

V:Value数据本身,其中Value本身也可以包含TLV

接下来我们以PHP形式的方式来讲解TLV,在PHP中TLV其表现形式可以用数组来表示,如下:

<?php

$tag = 0x103

       $value = “Test TLV”;

       $ret = array($tag,strlen($value),$value);

print_r($ret);

 

在这段代码中数据ret就是TLV在PHP中的表示。其中strlen($value)为TLV中的Length(T),其中需要注意的是$tag和length必须为int类型。当然这段代码并不完整。以下代码段是对TLV进行了处理的TLV。

<?php

/**

TLV包解析类

*/

 

class Tlv {

       private $buffer;

       private $t_len = 4;                //T长度

       private $l_len = 4;                //L长度

       private $buf_len =0;          //字节流长度

       private $buf_array = array();

      

       /**

        * 构造函数

        */

       function __construct(){}

      

       /**

        * 解析数据

        *

        * @param byte $buffer       二进制流数据

        * @param  $IsArray

        * @return array

        */

       function Read($buffer,$IsArray=false){

              $this->buffer = $buffer;

              $this->buf_len = strlen($this->buffer);

             

              $isMore = false;

              $tmp_array = array();

              $tmp_key = "";

             

              //清空数组

              if(isset($this->buf_array)){

                     unset($this->buf_array);

                     $this->buf_array = array();

              }

             

              $i=0;             

              while($i<$this->buf_len){

                     //获取TGA

                     $t = $this->getLength($i,$this->t_len);

                     if($this->toHex($t) == "0xffffffff") break;

                    

                     $i += $this->t_len;

                    

                     //获取Length

                     $l = $this->getLength($i,$this->l_len);

                     $i += $this->l_len;

                    

                     //获取Value

                     $v = substr($this->buffer,$i,$l);

                     $i += $l;

                    

                     if($IsArray){

                            $this->buf_array[$this->toHex($t)] =array($this->toHex($t),$l,$v);

                     }else{

                            array_push($this->buf_array,array($this->toHex($t),$l,$v));

                     }

              }

             

              return $this->buf_array;

       }

      

 

       //将数组转换二进制数据

       function Write($arrdata){

              $i = 0;

              $msg = null;         

              while($i<count($arrdata)){

                     $msg .= $this->Pack("N*",$arrdata[$i][0]);

                     $msg .= $this->Pack("N*",$arrdata[$i][1]);

                     $msg .= $arrdata[$i][2];

                    

                     $i += 1;

              }

             

              return $msg;

       }

      

      

       //获取值

       function getValue($key){

              return $this->buf_array[$key][2];

       }

      

       //转换成十六进制

       function toHex($value){

              return "0x".dechex($value);

       }

      

       //压包

       function Pack($format,$data){

              return pack($format,$data);

       }

      

       //解包

       function Unpack($format,$data){

              $ret = unpack($format,$data);

              return $ret[1];

       }

      

       //清楚所有数据

       function Clear(){

              if(isset($this->buffer)){

                 unset($this->buffer);

              }

              $this->buf_len = 0;

       }

      

}

<?php

/**

客户端上行包

*/

 

class Packet_0x103  extends Tlv {

      

       function GetPack(){

$tag = 0x103

$value = Tlv::Write(“Test TLV”);

              $ret = array($tag,strlen($value),$value);

              return Tlv::Write($ret);

       }

      

       function Clear(){

              if(isset($this->Pack_arry)){

                     unset($this->Pack_arry);

              }

       }

}

<?php

/**

客户端上行发送数据

*/

 

require("Tlv.class.php");

require("Packet.0x103.php");

 

$Packet = new Packet_0x103();

$data = $Packet->GetPack();

$Packet->Clear();

 

$conn = fsockopen("192.168.87.1",80,$errno,$errstr,1);//发送到服务端的地址和端口号

if(!$conn) die($errstr)."<br/>";//加上连接是否有效判断,就不会一直刷了

fwrite($conn,"POST /www.test.com/htdocs/All.php HTTP/1.1\r\n");//实际上就是将数据POST 到http://localhost:80/index.php

fwrite($conn,"Host:192.168.87.1\r\n");

fwrite($conn,"Connection:close\r\n");//这里加上会快一些。

fwrite($conn,"Content-length:".strlen($data)."\r\n\r\n");

fwrite($conn,$data);

while(!feof($conn))

{

    $content .= fgets($conn,128);

}

fclose($conn);

echo $content;

 

 

<?php

/**

接收从数据端发送过来的数据包

*/

 

header('content-type:text/html;charset="utf-8"');

 

//获取从客户端POST来的字节流

$Stream =file_get_contents("php://input");

 

$tlv = new TLV();

$data = $tlv->Read($Stream);

 

echo $data;

 

?>

www.meiju.la

 

 

 

posted on 2013-01-05 13:02  Docolour  阅读(703)  评论(0)    收藏  举报