使用.Net的NetworkStream.Read/BeginRead定界应用程序协议帧

时间:2011-09-15 14:00:38

标签: c# tcp networkstream modbus

我的问题更常见于网络编程,但因为我正在尝试编写Modbus TCP服务器(slave),我将用它来说明我的问题。

在Modbus TCP帧中,帧的第5个和第6个字节给出帧的大小:
字节1& 2:交易ID
字节3& 4:协议标识

字节5& 6:帧中剩余多少字节
bytes 7 - n:帧的其余部分。

使用NetworkStream.Read() / BeginRead()时,如何划分收到的帧?

我已经看到一些开源实现只读取前6个字节,解析字节5和6以获得帧的其余部分的大小,然后读取帧的其余部分。但是如果你的框架中没有开始和结束分隔符,你怎么知道框架的开始和结束位置?

例如,也许客户端发送了一些垃圾字符,然后发送了一个好的帧。在这种情况下,如果我只读取前6个字节,我会错过好帧,可能还有未来的帧,因为我与客户端的节奏不同步。

此问题并非特定于Modbus,而是针对使用“大小”字段指定帧大小的任何协议。你如何划分框架?

我觉得我缺少网络编程的基本功能,但协议可能没有精心设计。

1 个答案:

答案 0 :(得分:1)

客户端不应该在大多数Internet协议中发送乱码:如果客户端发送垃圾,服务器将发送错误并关闭连接。如果客户端想要继续与服务器通信,则需要创建新连接并且此时表现正常。

有些协议使用Self-synchronizing code。这允许收件人从流中的任何位置找到下一帧的开始。