C# 优雅处理通信中的粘包和断包(三) 处理使用结束符的协议
前言
之前我们已经讲过了两种常见的协议格式,分别是 固定长度的协议
和非固定长度的协议
。
今天我们来讲第三种常见的协议格式——使用结束符的协议
。
分析协议格式
看一下这个图,这个协议有什么特点呢?
它是由协议头部、有效数据、校验码、协议尾部构成。
与上一篇文章中所给出的那个协议不太一样,它并没有在数据包内注明当前数据包的总长度到底是多长,而是通过一个“头部”和一个“尾部”来进行匹配,从中截取数据包的有效的内容。
看两个示例,这里预设的协议头部是AA BB,协议尾部是EE FF。有效数据和校验位就在两者之间,看起来和上一篇文章中的协议格式有点相似,不同点在于数据包内部并没有用于注明长度的字节。
这种协议常用于明文字符串类型数据的通信,如AT指令等。
视频教程
【女朋友都能学会】C# 协议解包器(优雅处理粘包断包)
源代码
按照上方这个协议去实现与之匹配的解包器:
/// <summary>
/// 非固定长度的协议解包器
/// 通过匹配特定的协议起始标记和结束标记来截取数据包
/// </summary>
public class SimpleData3Unpacker : Unpacker
{
private byte[] EndMark { get; } = new byte[] { 0xEE, 0xFF };
public SimpleData3Unpacker()
{
StartMark = new byte[] { 0xAA, 0xBB };
}
protected override int CalculatePacketLength(IEnumerable<byte> bytes)
{
var index = bytes.IndexOf(EndMark);
if (index < 0)
{
return 0;
}
else
{
return index + EndMark.Length;
}
}
}
代码中在匹配协议尾部时使用了扩展方法IndexOf
:
var index = bytes.IndexOf(EndMark);
这是来自CodePuls扩展库的用于实现简单模式匹配(KMP算法)的扩展方法。通过NuGet即可安装,安装方法请参考文章:C# byte数组转十六进制字符串只需要一行代码
当然也可以手动实现简单的模式匹配算法来对协议尾部进行查找,KMP算法可以参考文章:C语言实现串的基本模式匹配
结束语
到此,BytesIO中协议解包器相关的基础部分已经完成了,在开发中遇到问题欢迎在评论区留言,也欢迎加入Q群中讨论。
此外项目的源代码我也会打包共享到群文件中,如有需要可以加群获取。
Q群:738018341
相关文章
C# 优雅处理通信中的粘包和断包(一) 处理固定长的的协议
C# 优雅处理通信中的粘包和断包(二) 处理非固定长度的协议
C# 优雅处理通信中的粘包和断包(三) 处理使用结束符的协议