`

uint8_t正则表达式库来分割TLV类型的网络数据包

 
阅读更多

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个完整协议包后,则才认为真正解析成功,否则一直丢弃直到满足深度的完整的包。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics