如何解析接收到的可变长度数据
How to parse received data with variable length
假设我正在接收一个具有可变长度数据负载的数据包。
**byte_num** **size** **type**
0 1 Length
1 1 SrcArsDev
2 4 Src_ID
6 1 DstArsDev
7 4 Dst_ID
11 4 Session
15 1 CMD
16 N N bytes payload N<=96
16+N 2 CRC
将通过SPI 通信接收数据。解析数据包以便我以后可以处理不同元素的一般方法是什么?
你能告诉我一个简单的 function/routine 填充结构元素吗?
一种方法是定义表示最大可能数据包大小的打包结构:
#pragma pack(push,1) // make sure everything is packed to byte level
typedef struct {
uint8_t Length;
uint8_t SrcArsDev;
uint32_t Src_ID;
uint8_t DstArsDev;
uint32_t Dst_ID;
uint32_t Session;
uint8_t CMD;
uint8_t payload[96 + 2]; // payload + CRC
} Message;
#pragma pack(pop) // restore struct packing
您的读取例程然后直接读取到这样的结构,然后消息的所有元素随后都可以作为结构中的字段进行访问。
唯一棘手的部分是您需要计算出实际 CRC 字节基于 Length
的位置,然后从 payload[]
缓冲区中提取这些字节,但这并不难:
Message msg;
ssize_t n = read(fd, &msg, sizeof(msg)); // read data into `msg`
uint16_t crc = *(int16_t*)&msg.payload[msg.Length]; // extract CRC
// validate CRC + perhaps also verify that n is consistent with msg.Length
// then access elements as needed:
src_id = msg.Src_ID;
dst_id = msg.Dst_ID;
当你不介意用特殊函数校验CRC时,你可以像@Paul定义的那样转换一个struct。当你读取了inputbuf后,你可以使用
struct *Message payload;
payload = (Message *) inputbuf;
现在您无需先复制有效负载成员即可访问它们。
假设我正在接收一个具有可变长度数据负载的数据包。
**byte_num** **size** **type**
0 1 Length
1 1 SrcArsDev
2 4 Src_ID
6 1 DstArsDev
7 4 Dst_ID
11 4 Session
15 1 CMD
16 N N bytes payload N<=96
16+N 2 CRC
将通过SPI 通信接收数据。解析数据包以便我以后可以处理不同元素的一般方法是什么?
你能告诉我一个简单的 function/routine 填充结构元素吗?
一种方法是定义表示最大可能数据包大小的打包结构:
#pragma pack(push,1) // make sure everything is packed to byte level
typedef struct {
uint8_t Length;
uint8_t SrcArsDev;
uint32_t Src_ID;
uint8_t DstArsDev;
uint32_t Dst_ID;
uint32_t Session;
uint8_t CMD;
uint8_t payload[96 + 2]; // payload + CRC
} Message;
#pragma pack(pop) // restore struct packing
您的读取例程然后直接读取到这样的结构,然后消息的所有元素随后都可以作为结构中的字段进行访问。
唯一棘手的部分是您需要计算出实际 CRC 字节基于 Length
的位置,然后从 payload[]
缓冲区中提取这些字节,但这并不难:
Message msg;
ssize_t n = read(fd, &msg, sizeof(msg)); // read data into `msg`
uint16_t crc = *(int16_t*)&msg.payload[msg.Length]; // extract CRC
// validate CRC + perhaps also verify that n is consistent with msg.Length
// then access elements as needed:
src_id = msg.Src_ID;
dst_id = msg.Dst_ID;
当你不介意用特殊函数校验CRC时,你可以像@Paul定义的那样转换一个struct。当你读取了inputbuf后,你可以使用
struct *Message payload;
payload = (Message *) inputbuf;
现在您无需先复制有效负载成员即可访问它们。