什么是TLV:
TLV是一种可变格式,意思就是:
Type类型, Lenght长度,Value值;
Type和Length的长度固定,一般那是2、4个字节(这里统一采用4个字节);
Value的长度有Length指定;
编码方法:
1.将类型type用htonl转换为网络字节顺序,指针偏移+4
2.将长度length用htonl转换为网络字节顺序,指针偏移+4
3.若值value数据类型为int、char、short,则将其转换为网络字节顺序,指针偏移+4;若值为字符串类型,写进后,指针偏移+length
解码方法:
1.读取type 用ntohl转换为主机字节序得到类型,指针偏移+4
2.读取lengh用ntohl转换为主机字节序得到长度;指针偏移+4
3.根据得到的长度读取value,若value数据类型为int、char、short,用ntohl转换为主机字节序,指针偏移+4;若value数据类型为字符串类型,指针偏移+length
其他说明:
类型(Type)字段是关于标签和编码格式的信息;
长度 (Length)字段定义数值的长度;
内容(Value)字段表示实际的数值。
因此,一个编码值又称TLV(Type,Length,Value)三元组。编码可以是基本型或结构型,如果它表示一个简单类型的、完整的显式值,那么编码就是基本型 (primitive);如果它表示的值具有嵌套结构,那么编码就是结构型 (constructed)。
PHP处理Demo
<?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);
//清空数组
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){
$msg = '';
for($i=0; $i<count($arrdata); $i++){
$msg .= $this->Pack("N*",$arrdata[$i][0]);
$msg .= $this->Pack("N*",$arrdata[$i][1]);
$msg .= $arrdata[$i][2];
}
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 getLength($start, $len){
return $this->Unpack('N*', substr($this->buffer, $start, $len));
}
//清楚所有数据
function Clear(){
if(isset($this->buffer)){
unset($this->buffer);
}
$this->buf_len = 0;
}
}
调用Demo:
$tlv = new Tlv();
//原始数据
$tag = 0x01;
$value = 'Hello World!';
$length = strlen( $value );
$data = array(
array($tag, $length,$value),
array($tag, $length,$value)
);
//组包
$data = $tlv->Write($data);
//解包
$result = $tlv->Read( $data );