c++ - 如何处理许多不同的输入二进制消息类型
问题描述
我有一个设备,我通过发送和接收特定的二进制数据包结构与之通信。该设备有一个定义良好的 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()
,但我很好奇是否有更好的设计可以用来增加添加新消息类型的灵活性、更好的可用性等。
解决方案
您可以尝试使用 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
推荐阅读
- django - 如何部分使用序列化程序
- ajax - Select2 动态选择 AJAX
- javascript - 如何获取数组中数组的长度?
- http - http2 中的 half close 有什么作用?http2中流状态的本地和远程之间的区别是什么?
- javascript - Laravel多行输入/选择下拉菜单时自动填写一行文本框字段
- r - 在 R 中,如何在语句末尾(句号)而不是在句子之间的 .(点)处拆分文本/段落
- c# - 尝试通过 VSTO 将 Action 作为参数传递给 COM 方法时出现 System.ArgumentException
- php - 提交一个表单导致提交另一个表单:页面中的 3 个 Html 表单
- javascript - 如何使用循环连接 socket.io 客户端
- mongodb - 认证 mongo 部署在 kubernetes 上