如何处理许多不同的输入二进制消息类型

问题描述 投票:0回答:1

我有一个通过发送和接收特定二进制数据包结构与之通信的设备。该设备有一个定义良好的API,但它可以返回100多种可能的消息类型。用于处理这些不同消息类型的好设计是什么?

这是伪代码的一个例子,我忽略了帧,校验和字节使它更清晰。

// I receive this message, where 0x00 indicates the device status,
//and each other byte is a particular error or status
message = [0x00, 0x01, 0x01, 0x04]
// The next message I receive, where 0x10 indicates system time, 
// and the rest of the fields are the integer clock seconds of the device.
message = [0x10, 0x00, 0x32, 0xFF, 0x8E]
// 100 other message types....

正如您所看到的,我收到的每条消息都需要稍微不同的处理,具有不同的含义。我本来打算使用一个巨大的切换语句case 0x00: process_errors() case 0x10: process_time(),但我很好奇是否有更好的设计,我可以用来增加添加新消息类型的灵活性,更好的可用性等。

c++ design-patterns io
1个回答
1
投票

您可以尝试使用TLV(标签长度值)实现。它有利于处理数据流。

标记 - 这将是一个数据字节(根据您的示例),它标识后面的消息类型。要使用它,您应该事先知道哪种消息类型有多少数据。例如,在0x00(设备状态)的情况下,您现在应该事先确定接下来的3个字节是数据。

长度 - 数据字节的长度

价值 - 实际数据

这是你可以做的: 1)准备系统支持的不同消息的标签和长度的映射。 2)连续接收数据字节。 3)读取第一个字节(这将是标签)并确定它是什么类型的消息。在你的情况下,这将给你0x00,0x10等。 4)请参阅您的标签和长度信息图。您将确定需要进一步读取的数据字节数。 5)读取数据部分后,接收器应准备好接收下一条消息(准备读取下一个标签)

这就是阅读消息。获得消息及其数据后,您可以随意使用它。例如,除了与Tag对应的消息长度之外,您还可以注册一个函数。这将允许您调用特定函数及其所需的参数。

设备状态

Data Tag = 00  
Data Length = 03  
Data Value =  01 01 04 

系统时间

Data Tag = 10  
Data Length = 04  
Data Value =  00 32 FF 8E  
© www.soinside.com 2019 - 2024. All rights reserved.