111,094
社区成员




class 测试
{
static void Main(string[] args)
{
var 分割器 = new 数据帧分割器();
分割器.数据帧收悉事件 += (s, e) =>
{
// 这里可以自行添加校验代码 ThrowOnCorruptedData(e.数据帧);
// ...
Console.WriteLine(BitConverter.ToString(e.数据帧));
Console.WriteLine(Encoding.UTF8.GetString(e.数据帧, 1, e.数据帧.Length - 3));
Console.WriteLine();
};
分割器.添加数据(Encoding.ASCII.GetBytes("~first frame\r")); // 假设收到这些数据
分割器.添加数据(new byte[] { 8, 8 }); // 假设校验码是0x08, 0x08
分割器.添加数据(Encoding.ASCII.GetBytes("~second fram"));
分割器.添加数据(new byte[] { (byte)'e', (byte)'\r', 0x78, 0x9a }); // 假设校验码是0x78, 0x8a
Console.ReadLine();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class 数据帧分割器
{
const byte 起始标志 = 0x7E;
const byte 结束标志 = 0x0D;
const int 校验码长 = 2;
List<byte> _待处理数据 = new List<byte>();
public void 添加数据(byte[] data)
{
添加数据(data, 0, data.Length);
}
public void 添加数据(byte[] data, int offset, int count)
{
_待处理数据.AddRange(new ArraySegment<byte>(data, offset, count));
var 起始位置 = _待处理数据.IndexOf(起始标志);
if (起始位置 < 0) return; // 尚未收到起始标志
var 结束位置 = _待处理数据.IndexOf(结束标志, index: 起始位置);
if (结束位置 < 0 || _待处理数据.Count < 结束位置 + 校验码长) return; // 尚未收到结束标志 + 校验码
var frame = new byte[结束位置 + 校验码长 + 1 - 起始位置];
_待处理数据.CopyTo(起始位置, frame, 0, frame.Length); // 把数据帧割出
_待处理数据 = new List<byte>(_待处理数据.Skip(结束位置 + 校验码长 + 1)); // 把剩余数据留下
数据帧收悉事件?.Invoke(this, new DataFrameEventArgs() { 数据帧 = frame }); // 激发数据帧收悉事件
}
public event EventHandler<DataFrameEventArgs> 数据帧收悉事件;
public class DataFrameEventArgs : EventArgs
{
public byte[] 数据帧 { get; set; }
}
}