uint8_t正则表达式库来分割TLV类型的网络数据包
两种读取协议包方法
基本上所有的网络通信,包括底层的TCP/IP包,均采用Type-Length-Value的协议格式。
读取网络数据包,有两种方式:
1、先从底层读取由Type和Length组成的head部分,然后根据length来读取value部分,最后根据读取的两部分组成一封完整的协议包。
2、不管从底层读取的是哪一部分,直接丢在buffer中,然后由另外一个线程来从buffer中取出部分数据来解析分割得到一封完整的协议包。
两种方式各有利弊:
第一种,不需要另外的buffer来缓存从底层读到的数据,因为是直接读取,直接组成了一个完整的协议包。但是如果发生错位(发送方发错了或者是接收方解析错误)将后导致后续的所有协议包均发生错位。
第二种,由于是从buffer中取数据并解析,因此即使个别协议包不完整或者错误,也不影响其他的协议包。但是需要一个buffer来缓冲,以及需要一个机制来从buffer中解析得到完整的协议包。
在上第二篇日志中,针对第二种方法中的buffer设计了流数据缓冲库,此篇日志中,将针对解析数据得到协议包进行讨论。
PCRE正则表达式
采用正则表达式来解析得到完整的协议包,使用的正则表达式库是PCRE。
无法支持!!!!!!!!!!!!因为正则表达式中,有很多特殊公式字符,而网络协议通信包里面什么都有,则根本无法进行匹配。
解决方案是自己写个可以匹配uint_8串的库,并且专用于TLV格式的数据的匹配。
TLV数据包格式特点如下:
(1)Byte的范围是0x00到0xFF
(2)Head包括Type和Length,长度固定
(3)Value长度不固定,取决于Length
0Xff == ?
0xFe == length
0xfd == *
例如一个协议格式如:【0x100x1f】【16 reserve】【2 msg type】【2 value lenth】【n value】
则正则表达式可以写做:0x100x1f 0xfe(18) 0xfe 0xfe 0xfd
满足两个条件即可判断为一个完整的协议帧:
(1)以0x10 0x1f分割得到不同的准数据帧
(2)检查数据帧中value的长度是否等于value length
(3)并且后续的n个准数据帧也是对的,解析深度
Int uint8RESetExpression( uint8_t* str, intlen); //设置如上的表达式
Int uint8RESetHeadStableValue( int start,int end, uint8_t** value, int flen, int slen);//设置头部中独立区有限的取值范围,例如msg type(19-20)是固定个数的,可以设置多个。
Int uint8RESetValueLenOffSet( int offset );//例如value length比实际value长4,则uint8RESetValueLenOffSet(4)
Int uint8RESetDepth(int n) //解析深度指当得到一个完整协议包后,如果后面还有足够的数据,则能够解析出后面的n个完整协议包后,则才认为真正解析成功,否则一直丢弃直到满足深度的完整的包。