jy-plc/Services/models/NetPackage.cs

122 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
namespace IceCoffee.HJ212.Models
{
/// <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}";
}
}
}