120 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
	
	
using System.Text;
 | 
						|
 | 
						|
namespace langguanApi.Model
 | 
						|
{
 | 
						|
    /// <summary>
 | 
						|
    /// 通讯包
 | 
						|
    /// </summary>
 | 
						|
    public class NetPackage
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// 默认头
 | 
						|
        /// </summary>
 | 
						|
        public const string FixedHead = "##";
 | 
						|
        /// <summary>
 | 
						|
        /// 默认尾
 | 
						|
        /// </summary>
 | 
						|
        public const string FixedTail = "\r\n";
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 包头
 | 
						|
        /// </summary>
 | 
						|
        public string Head { get; set; }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 数据段长度
 | 
						|
        /// </summary>
 | 
						|
        public int DataSegmentLength { get; set; }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 数据段
 | 
						|
        /// </summary>
 | 
						|
        public DataSegment DataSegment { get; set; }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// CRC校验码
 | 
						|
        /// </summary>
 | 
						|
        public string CrcCode { get; set; }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 包尾
 | 
						|
        /// </summary>
 | 
						|
        public string Tail { get; set; }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// CRC16校验
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="arg">需要校验的字符串</param>
 | 
						|
        /// <returns>CRC16 校验码</returns>
 | 
						|
        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');
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 解析
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="line"></param>
 | 
						|
        /// <param name="unpackCacheFunc"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public static NetPackage Parse(string line, Func<StringBuilder> 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);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 序列化
 | 
						|
        /// </summary>
 | 
						|
        /// <returns></returns>
 | 
						|
        public string Serialize()
 | 
						|
        {
 | 
						|
            string dataSegment = DataSegment.Serialize();
 | 
						|
            DataSegmentLength = dataSegment.Length;
 | 
						|
            CrcCode = CRC16(dataSegment);
 | 
						|
 | 
						|
            return $"{Head}{DataSegmentLength.ToString().PadLeft(4, '0')}{dataSegment}{CrcCode}{Tail}";
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |