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个完整协议包后,则才认为真正解析成功,否则一直丢弃直到满足深度的完整的包。
分享到:
相关推荐
提供了一种将uint32_t格式的数据转换为int格式数据的方法,在点云数据转换等领域具有一定的实际应用意义。
uint128_t C ++的无符号128位整数类型版权所有(c)2013-2018 Jason Lee @ calccrypto在gmail.com 请参阅许可文件以获得许可。致谢在Auston Sterling的大力帮助下感谢StefanDeigmüller找到操作员中的错误*。 感谢...
2.进入void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )函数,可看到如下关键代码: 当接收完成时调用该函数,在此函数内能够读取到接收到的数据、收到数据的长度、信号强度、信噪比。 ...
uint256_t C ++的无符号256位整数类型 版权所有(c)2013-2018 Jason Lee @ calccrypto在gmail.com 请参阅许可文件以获得许可。 致谢 在Auston Sterling的大力帮助下 感谢StefanDeigmüller找到操作员中的错误*。 ...
int8_t uint8_t Integer type with a width of exactly 8, 16, 32, or 64 bits. For signed types, negative values are represented using 2's complement. No padding bits. Optional: These typedefs are not ...
uint8_t Program_verify(uint8_t* buff1, uint8_t* buff2, uint32_t count); void WB_Serial_NAND_Pageprogram_Pattern(uint8_t addh, uint8_t addl, uint8_t* program_buffer, uint32_t count); void WB_Serial_...
int8_t LTC2666_write(uint8_t cs, uint8_t dac_command, uint8_t dac_address, uint16_t dac_code); float LTC2666_code_to_voltage(uint16_t dac_code, float min_output, float max_output);
int8_t LTC2666_write(uint8_t cs, uint8_t dac_command, uint8_t dac_address, uint16_t dac_code); float LTC2666_code_to_voltage(uint16_t dac_code, float min_output, float max_output);
本文给大家分享的是笔者实现的仿uint64_t的类,可以用在不支持uint64_t的平台上,虽然现在功能还不完善,但是还是分享给大家,也算是给大家一个思路吧。
uint8_t I2C_WriteNByte(uint8_t sla, uint8_t suba_type, uint32_t suba, uint8_t *s, uint32_t num ,LPC_I2C_TypeDef *LPC_I2Cx); //通用的I2C写函数 uint8_t I2C_ReadNByte (uint8_t sla, uint8_t suba_type, ...
uint8_t DS18B20_Check(uint8_t sdaPORT); uint8_t DS18B20_Read_Bit(uint8_t sdaPORT); uint8_t DS18B20_Read_Byte(uint8_t sdaPORT); void DS18B20_Write_Byte(uint8_t dat,uint8_t sdaPORT); void DS18B20_Start...
uint8_t WM8978_Write_Reg(uint8_t reg,uint16_t val) { uint8_t res; uint8_t RegAddr; uint8_t RegValue; RegAddr=(reg)|((uint8_t)((val>>8)&0x01)); RegValue=(uint8_t)val; res=IIC_Write_One_Byte(WM...
将main函数中void VL6180X_WriteByte(uint16_t reg,uint8_t data); uint8_t VL6180X_ReadByte(uint16_t reg); uint8_t VL6180X_Read_ID(); uint8_t VL6180X_Init(); uint8_t VL6180X_Read_Range(); 以及vl6180.h放入...
uint8_t W25QXX_ReadSR(void); //读取状态寄存器S void W25QXX_Write_SR(uint8_t sr); //写状态寄存器 void W25QXX_Write_Enable(void); //写使能 void W25QXX_Write_Disable(void); //写保护 void W25QXX_Write...
uint16_t aes_encrypt(uint8_t *iv,uint8_t *Key,uint8_t *input,uint16_t length)/*加密时,明文首先与IV异或,然后将结果进行块加密,得到的输出就是密文, *同时本次的输出密文作为下一个块加密的IV*/ void aes_...
#ifndef uint8_t #define uint8_t unsigned char #endif #ifdef __cplusplus extern C { #endif typedef struct { uint8_t key[32]; uint8_t enckey[32]; uint8_t deckey[32]; } aes256_context; void aes256_...
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv); void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv); void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* ...
static uint8_t Voltage_Check(void); static void Servo_Handle(uint8_t * p_flag); static void Power_transfer_Handle(uint8_t * p_flag); static void Over_current_Handle(uint8_t * p_flag); static void Over...
uint16_t 类型; uint16_t 版本; uint16_t 块; uint16_t CRC; uint16_t BLVersion; } 请求固件配置; 网关(控制器)使用 NodeFirmwareConfig 进行响应,其中包括有关传感器应执行的固件的详细信息: ...
uint8_t g_pcom1RxBuffer[UART1_MAXBUFFERSIZE],gRevUART1Ok; uint16_t g_u16com2RxCnt,g_dwcom2CurRcvLen; uint8_t g_pcom2RxBuffer[UART2_MAXBUFFERSIZE],gRevUART2Ok; uint16_t g_u16com3RxCnt,g_dwcom3...