我有一个正在通过发送和接收特定的二进制数据包结构进行通信的设备。该设备具有定义明确的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....
如您所见,我收到的每条消息都需要稍作处理,具有不同的含义。我本来打算使用巨大的switch语句case 0x00: process_errors() case 0x10: process_time()
,但我很好奇是否可以使用更好的设计来增加添加新消息类型的灵活性,更好的可用性等。
答案 0 :(得分:1)
您可以尝试使用TLV(标记长度值)实现。这对于处理数据流非常有用。
标记-这将是一个字节的数据(按照您的示例),用于标识后面的消息类型。为此,您应该事先知道哪种消息类型具有多少数据。例如,在0x00(设备状态)的情况下,您现在应该事先将接下来的3个字节作为数据。
长度-数据字节的长度
值-实际数据
这是您可以做的:
1)准备系统支持的不同消息的标签和长度的映射。
2)连续接收数据字节。
3)读取第一个字节(这将是标签),并确定它是哪种消息。您的情况将为您提供0x00、0x10等。
4)请参阅您的标签和长度信息图。您将确定需要进一步读取多少字节的数据。
5)读取数据部分后,您的接收器应准备好接收下一条消息(准备读取下一个标签)
这都是关于阅读消息的。收到消息及其数据后,就可以随意使用它。例如,除了与标签相对应的消息长度外,您还可以注册功能。这样一来,您就可以调用特定的函数以及所需的参数。
设备状态
Data Tag = 00
Data Length = 03
Data Value = 01 01 04
系统时间
Data Tag = 10
Data Length = 04
Data Value = 00 32 FF 8E