开源TCP、UDP、串口等流式数据解码库C#源码
- 实现解码自由
- 底层缓冲区采用数据池实现
- 通过使用池化缓冲区来消除大型对象堆分配
- 减少GC次数
- 缓冲区实现IBufferWrite接口
- 广泛支持较新的内存相关类型,如Span<byte>, ReadOnlySpan<byte>以及Memory<byte>
- 避免内存碎片
- 提供出色的性能
介绍TCP是面向连接的传输协议,TCP传输的数据是以流的形式,而流数据是没有明确的开始结尾边界,应用层处理接收数据时可能产生半包或者粘包,其主要原因如下: - TCP发送方原因:
因为TCP本身传输的数据包大小就有限制,所以应用发出的消息包过大,TCP会把应用消息包拆分为多个TCP数据包发送出去。
Negal算法的优化,当应用发送数据包太小,TCP为了减少网络请求次数的开销,它会等待多个消息包一起,打成一个TCP数据包一次发送出去。 - TCP接收方原因:
因为TCP缓冲区里的数据都是字符流的形式,没有明确的边界,因为数据没边界,所以应用从TCP缓冲区中读取数据时就没办法指定一个或几个消息一起读,而只能选择一次读取多大的数据流,而这个数据流中就可能包含着某个消息包的一部分数据。
所以为了解决半包或者粘包,得到应用层需要的数据,实现解码自由,开发了此数据解码库,原理也就是给数据流转时给流式数据加上消息边界。在接收数据时,将流式数据通过相应的解码器(FrameDecoder),解码输出完整的帧数据(FrameData)。 UDP是面向消息的,它有边界协议,可以根据消息的格式区分消息的开始和结尾。那为什么还要解码呢?
举个例子,实际项目:FPGA通过千兆网卡将数据以UDP协议输出,其数据实际还是流式数据,需要在UDP接收到的数据中寻找包头和包尾,来截取一段需要的数据,这样数据解码器就有意义了。 串口在数据发送和接收时,根据串口的配置(波特率、奇偶校验等)、串口缓冲设置、数据发送间隔的不匹配,也会出现接收数据时可能产生半包或者粘包。
Modbus-RTU总线是通过时间间隔来判断一帧数据结束的,3.5个字符时间内没有收到新的数据,则认为这一帧数据结束。
普通的串口数据传输,还是要给数据增加消息边界,通过解码器来获取实际需要的数据。 其实不限于TCP、UDP、串口,只要是从流式数据中获取指定格式的数据,都可以用过解码器来实现。
开源TCP、UDP、串口等流式数据解码库C#源码
流式数据有两种: 针对这两种数据,实现了泛型数据缓存: DataCache<T>,其内存分配通过数据池:DataPool<T> 实现
通过DataCache<byte>实现字节数据组缓存,通过DataCache<char>实现字符串缓存 提取码下载:
|