using System; using System.Collections.Generic; using System.Text; namespace IceCoffee.HJ212.Models { /// /// 通讯包 /// public class NetPackage { /// /// 默认头 /// public const string FixedHead = "##"; /// /// 默认尾 /// public const string FixedTail = "\r\n"; /// /// 包头 /// public string Head { get; set; } /// /// 数据段长度 /// public int DataSegmentLength { get; set; } /// /// 数据段 /// public DataSegment DataSegment { get; set; } /// /// CRC校验码 /// public string CrcCode { get; set; } /// /// 包尾 /// public string Tail { get; set; } /// /// CRC16校验 /// /// 需要校验的字符串 /// CRC16 校验码 private static string CRC16(string arg) { char[] puchMsg = arg.ToCharArray(); uint i, j, crc_reg, check; crc_reg = 0xFFFF; for (i = 0; i < puchMsg.Length; i++) { crc_reg = (crc_reg >> 8) ^ puchMsg[i]; for (j = 0; j < 8; j++) { check = crc_reg & 0x0001; crc_reg >>= 1; if (check == 0x0001) { crc_reg ^= 0xA001; } } } return crc_reg.ToString("X2").PadLeft(4, '0'); } /// /// 解析 /// /// /// /// public static NetPackage Parse(string line, Func unpackCacheFunc = null) { try { NetPackage netPackage = new NetPackage(); netPackage.Head = line.Substring(0, 2); netPackage.DataSegmentLength = int.Parse(line.Substring(2, 4)); string dataSegment = line.Substring(6, netPackage.DataSegmentLength); string crcCode = line.Substring(6 + netPackage.DataSegmentLength, 4); string calcCrcCode = CRC16(dataSegment); if (crcCode != calcCrcCode) { throw new Exception("CRC校验失败 " + line); } netPackage.DataSegment = DataSegment.Parse(dataSegment, unpackCacheFunc); netPackage.CrcCode = crcCode; netPackage.Tail = line.Substring(10 + netPackage.DataSegmentLength); return netPackage; } catch (Exception ex) { throw new Exception("Error in NetPackage.Parse", ex); } } /// /// 序列化 /// /// public string Serialize() { string dataSegment = DataSegment.Serialize(); DataSegmentLength = dataSegment.Length; CrcCode = CRC16(dataSegment); return $"{Head}{DataSegmentLength.ToString().PadLeft(4, '0')}{dataSegment}{CrcCode}{Tail}"; } } }