串行数据的二进制通信协议解析器设计
我正在重新审视字节流的通信协议解析器设计(串行数据,一次接收1个字节)。
数据包结构(不能更改)是:
|| Start Delimiter (1 byte) | Message ID (1 byte) | Length (1 byte) | Payload (n bytes) | Checksum (1 byte) ||
过去,我已经采用程序状态机方法实现了这样的系统。当每个数据字节到达时,状态机被驱动以查看输入数据一次/一个字节是否适合有效数据包,并且一旦整个数据包被组装,基于消息ID的switch语句执行适当的消息处理程序。在一些实现中,解析器/状态机/消息处理程序循环位于其自己的线程中,以便不对串行数据接收的事件处理程序造成负担,并且由指示字节已被读取的信号量触发。
我想知道是否有更优雅的解决方案来解决这个常见问题,利用C#和OO设计的一些更现代的语言功能。任何可以解决这个问题的设计模式?事件驱动vs polled vs组合?
我很想听听你的想法。谢谢。
Prembo。
没有找到相关结果
已邀请:
3 个回复
嗜蒂谷尘旱
编辑:对此处发生的事情的一些解释: 第一:
该行是C#属性(由
定义)表示
类接受消息id为5。 第二: 是的,字典是在运行时通过反射构建的。你只需要这样做一次(我会把它放到一个单例类中,你可以在其上放置一个可以运行的测试用例,以确保字典正确构建)。 第三:
这一行从字典中获取以下编译的lambda表达式并执行它:
(由于delagates如何工作的协变性变化,在.NET 3.5中必须使用强制转换,但在4.0版本中不需要强制转换,在4.0中,可以将类型为
的对象分配给类型为
的对象。) 这个lambda表达式是在字典创建过程中由Value赋值行构建的:
(此处的强制转换是将已编译的lambda表达式转换为
的必要条件。) 我是这样做的,因为我恰好已经拥有了那种可用的类型。你也可以使用:
但我相信这会更慢(而且这里的演员阵容有必要将ѭѭ改为
)。 第四:
之所以这样做是因为我觉得你可能有必要在课堂上不止一次地放置
(每个班级接受一个以上的留言ID)。这也有忽略没有消息id属性的消息类的好的副作用(否则Where方法需要具有确定属性是否存在的复杂性)。
襄挟款籍
田眯衅