Files
Modbus.Net/Modbus.Net/Modbus.Net.Modbus/ModbusProtocolLinkerBytesExtend.cs
2026-04-04 17:25:15 +08:00

593 lines
28 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Modbus.Net.Modbus
{
/// <summary>
/// Modbus 协议字节伸缩类 / Modbus Protocol Bytes Extend Classes
/// <remarks>
/// 实现各种 Modbus 协议的字节扩展和收缩功能
/// Implements bytes extend and reduce functionality for various Modbus protocols
/// <para>
/// 主要类 / Main Classes:
/// <list type="bullet">
/// <item><strong>ModbusTcpProtocolLinkerBytesExtend</strong> - TCP 协议 MBAP 头处理 / TCP protocol MBAP header handling</item>
/// <item><strong>ModbusRtuProtocolLinkerBytesExtend</strong> - RTU 协议 CRC16 处理 / RTU protocol CRC16 handling</item>
/// <item><strong>ModbusAsciiProtocolLinkerBytesExtend</strong> - ASCII 协议 LRC 和格式处理 / ASCII protocol LRC and format handling</item>
/// <item><strong>ModbusRtuInTcpProtocolLinkerBytesExtend</strong> - RTU over TCP 透传 / RTU over TCP tunneling</item>
/// <item><strong>ModbusAsciiInTcpProtocolLinkerBytesExtend</strong> - ASCII over TCP 透传 / ASCII over TCP tunneling</item>
/// <item><strong>ModbusUdpProtocolLinkerBytesExtend</strong> - UDP 协议处理 / UDP protocol handling</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
#region UDP / UDP Protocol Bytes Extend
/// <summary>
/// Modbus RTU over UDP 字节伸缩 / Modbus RTU over UDP Bytes Extend
/// <remarks>
/// 继承自 ModbusRtuProtocolLinkerBytesExtend处理 RTU over UDP 协议
/// Inherits from ModbusRtuProtocolLinkerBytesExtend, handles RTU over UDP protocol
/// <para>
/// 特点 / Characteristics:
/// <list type="bullet">
/// <item>RTU 帧原样传输 / RTU frames transmitted as-is</item>
/// <item>无 MBAP 头 / No MBAP header</item>
/// <item>保留 CRC16 校验 / CRC16 checksum preserved</item>
/// <item>适用于 UDP 广播 / Suitable for UDP broadcast</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
public class ModbusRtuInUdpProtocolLinkerBytesExtend : ModbusRtuProtocolLinkerBytesExtend
{
// 使用 RTU 协议的字节伸缩方法 / Use RTU protocol bytes extend methods
}
/// <summary>
/// Modbus ASCII over UDP 字节伸缩 / Modbus ASCII over UDP Bytes Extend
/// <remarks>
/// 继承自 ModbusAsciiProtocolLinkerBytesExtend处理 ASCII over UDP 协议
/// Inherits from ModbusAsciiProtocolLinkerBytesExtend, handles ASCII over UDP protocol
/// </remarks>
/// </summary>
public class ModbusAsciiInUdpProtocolLinkerBytesExtend : ModbusAsciiProtocolLinkerBytesExtend
{
// 使用 ASCII 协议的字节伸缩方法 / Use ASCII protocol bytes extend methods
}
/// <summary>
/// Modbus UDP 协议字节伸缩 / Modbus UDP Protocol Bytes Extend
/// <remarks>
/// 继承自 ModbusTcpProtocolLinkerBytesExtend处理 UDP 协议
/// Inherits from ModbusTcpProtocolLinkerBytesExtend, handles UDP protocol
/// <para>
/// 特点 / Characteristics:
/// <list type="bullet">
/// <item>添加 MBAP 头 / Adds MBAP header</item>
/// <item>无连接模式 / Connectionless mode</item>
/// <item>适用于广播查询 / Suitable for broadcast query</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
public class ModbusUdpProtocolLinkerBytesExtend : ModbusTcpProtocolLinkerBytesExtend
{
// 使用 TCP 协议的字节伸缩方法 / Use TCP protocol bytes extend methods
}
#endregion
#region TCP / TCP Tunneling Protocol Bytes Extend
/// <summary>
/// Modbus RTU over TCP 字节伸缩 / Modbus RTU over TCP Bytes Extend
/// <remarks>
/// 继承自 ModbusRtuProtocolLinkerBytesExtend处理 RTU over TCP 透传协议
/// Inherits from ModbusRtuProtocolLinkerBytesExtend, handles RTU over TCP tunneling protocol
/// <para>
/// 使用场景 / Use Cases:
/// <list type="bullet">
/// <item>串口服务器 / Serial device server</item>
/// <item>通过 TCP 传输 RTU 帧 / Transmit RTU frames over TCP</item>
/// <item>远程串口访问 / Remote serial access</item>
/// </list>
/// </para>
/// <para>
/// 特点 / Characteristics:
/// <list type="bullet">
/// <item>RTU 帧原样传输 / RTU frames transmitted as-is</item>
/// <item>无 MBAP 头 / No MBAP header</item>
/// <item>保留 CRC16 校验 / CRC16 checksum preserved</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
public class ModbusRtuInTcpProtocolLinkerBytesExtend : ModbusRtuProtocolLinkerBytesExtend
{
// 使用 RTU 协议的字节伸缩方法 / Use RTU protocol bytes extend methods
}
/// <summary>
/// Modbus ASCII over TCP 字节伸缩 / Modbus ASCII over TCP Bytes Extend
/// <remarks>
/// 继承自 ModbusAsciiProtocolLinkerBytesExtend处理 ASCII over TCP 透传协议
/// Inherits from ModbusAsciiProtocolLinkerBytesExtend, handles ASCII over TCP tunneling protocol
/// <para>
/// 使用场景 / Use Cases:
/// <list type="bullet">
/// <item>串口服务器 / Serial device server</item>
/// <item>通过 TCP 传输 ASCII 帧 / Transmit ASCII frames over TCP</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
public class ModbusAsciiInTcpProtocolLinkerBytesExtend : ModbusAsciiProtocolLinkerBytesExtend
{
// 使用 ASCII 协议的字节伸缩方法 / Use ASCII protocol bytes extend methods
}
#endregion
#region TCP / TCP Protocol Bytes Extend
/// <summary>
/// Modbus/TCP 协议字节伸缩 / Modbus/TCP Protocol Bytes Extend
/// <remarks>
/// 实现 Modbus TCP 协议的 MBAP 头添加和移除功能
/// Implements MBAP header addition and removal for Modbus TCP protocol
/// <para>
/// MBAP 头格式 / MBAP Header Format:
/// <code>
/// [Transaction ID (2)][Protocol ID (2)][Length (2)][Unit ID (1)]
/// │ │ │ │ │ │
/// └─ 事务标识,用于匹配请求响应
/// └─ 协议标识Modbus=0
/// └─ 后续字节长度
/// └─ 从站地址
/// </code>
/// </para>
/// <para>
/// 使用示例 / Usage Example:
/// <code>
/// var bytesExtend = new ModbusTcpProtocolLinkerBytesExtend();
///
/// // 扩展 (发送前) / Extend (before sending)
/// byte[] rawData = [0x01, 0x03, 0x00, 0x00, 0x00, 0x0A]; // Modbus RTU 帧
/// byte[] extendedData = bytesExtend.BytesExtend(rawData);
/// // 结果:[0x00 0x01 0x00 0x00 0x00 0x06 0x01 0x03 0x00 0x00 0x00 0x0A]
/// // │ 事务 ID │ 协议 ID │ 长度 │RTU 帧...
/// ///
/// // 收缩 (接收后) / Reduce (after receiving)
/// byte[] receivedData = [0x00 0x01 0x00 0x00 0x00 0x06 0x01 0x03 0x04 0x00 0x64 0x00 0xC8];
/// byte[] reducedData = bytesExtend.BytesDecact(receivedData);
/// // 结果:[0x01, 0x03, 0x04, 0x00, 0x64, 0x00, 0xC8] // 移除 MBAP 头
/// </code>
/// </para>
/// </remarks>
/// </summary>
public class ModbusTcpProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
{
private static ushort _sendCount = 0;
private static readonly object _counterLock = new object();
/// <summary>
/// 协议扩展 (发送前调用) / Protocol Extend (Called Before Sending)
/// <remarks>
/// 在 Modbus TCP 协议数据前添加 MBAP 头 (6 字节)
/// Add MBAP header (6 bytes) before Modbus TCP protocol data
/// <para>
/// MBAP 头结构 / MBAP Header Structure:
/// <list type="bullet">
/// <item>Transaction ID (2 字节) - 事务标识,用于匹配请求响应 / Transaction identifier for matching request-response</item>
/// <item>Protocol ID (2 字节) - 协议标识Modbus=0 / Protocol identifier, Modbus=0</item>
/// <item>Length (2 字节) - 后续字节长度 / Length of following bytes</item>
/// <item>Unit ID (1 字节) - 从站地址 / Unit identifier (slave address)</item>
/// </list>
/// </para>
/// <para>
/// 事务计数 / Transaction Counting:
/// <list type="bullet">
/// <item>使用静态计数器 / Uses static counter</item>
/// <item>每次发送递增 / Increments on each send</item>
/// <item>模 65536 循环 (ushort 范围) / Cycles mod 65536 (ushort range)</item>
/// <item>线程安全 (使用锁) / Thread-safe (uses lock)</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
/// <param name="content">
/// 扩展前的原始协议内容 / Original Protocol Content Before Extension
/// <remarks>
/// Modbus RTU 帧 (包含从站地址、功能码、数据、CRC)
/// Modbus RTU frame (contains slave address, function code, data, CRC)
/// </remarks>
/// </param>
/// <returns>
/// 扩展后的协议内容 / Extended Protocol Content
/// <remarks>
/// 添加了 MBAP 头的完整 TCP 帧
/// Complete TCP frame with MBAP header added
/// </remarks>
/// </returns>
public byte[] BytesExtend(byte[] content)
{
// Modbus/TCP 协议扩展,前面加 6 个字节
// Modbus/TCP protocol extension, add 6 bytes at the front
// 前面 2 个为事务编号,中间两个为 0后面两个为协议整体内容的长度
// First 2: transaction ID, middle 2: 0, last 2: total length
var newFormat = new byte[6 + content.Length];
lock (_counterLock)
{
// 生成事务 ID (循环计数) / Generate transaction ID (cyclic count)
var transaction = (ushort)(_sendCount % 65536 + 1);
var tag = (ushort)0; // 协议标识Modbus=0 / Protocol ID, Modbus=0
var leng = (ushort)content.Length; // 后续字节长度 / Length of following bytes
// 复制事务 ID (大端格式) / Copy transaction ID (big-endian)
Array.Copy(BigEndianLsbValueHelper.Instance.GetBytes(transaction), 0, newFormat, 0, 2);
// 复制协议标识 / Copy protocol ID
Array.Copy(BigEndianLsbValueHelper.Instance.GetBytes(tag), 0, newFormat, 2, 2);
// 复制长度 / Copy length
Array.Copy(BigEndianLsbValueHelper.Instance.GetBytes(leng), 0, newFormat, 4, 2);
// 复制原始内容 / Copy original content
Array.Copy(content, 0, newFormat, 6, content.Length);
_sendCount++; // 递增计数器 / Increment counter
}
return newFormat;
}
/// <summary>
/// 协议收缩 (接收后调用) / Protocol Reduce (Called After Receiving)
/// <remarks>
/// 移除 Modbus TCP 协议数据的 MBAP 头 (6 字节)
/// Remove MBAP header (6 bytes) from Modbus TCP protocol data
/// <para>
/// 处理流程 / Processing Flow:
/// <list type="number">
/// <item>创建新数组,长度 = 原长度 - 6 / Create new array, length = original length - 6</item>
/// <item>从第 7 个字节开始复制 / Copy starting from 7th byte</item>
/// <item>返回纯 Modbus RTU 帧 / Return pure Modbus RTU frame</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
/// <param name="content">
/// 收缩前的完整协议内容 / Complete Protocol Content Before Reduction
/// <remarks>
/// 包含 MBAP 头的完整 TCP 帧
/// Complete TCP frame with MBAP header
/// </remarks>
/// </param>
/// <returns>
/// 收缩后的协议内容 / Reduced Protocol Content
/// <remarks>
/// 移除 MBAP 头后的 Modbus RTU 帧
/// Modbus RTU frame with MBAP header removed
/// </remarks>
/// </returns>
public byte[] BytesDecact(byte[] content)
{
// Modbus/TCP 协议收缩,抛弃前面 6 个字节的内容
// Modbus/TCP protocol reduction, discard first 6 bytes
var newContent = new byte[content.Length - 6];
Array.Copy(content, 6, newContent, 0, newContent.Length);
return newContent;
}
}
#endregion
#region RTU / RTU Protocol Bytes Extend
/// <summary>
/// Modbus/RTU 协议字节伸缩 / Modbus/RTU Protocol Bytes Extend
/// <remarks>
/// 实现 Modbus RTU 协议的 CRC16 校验码添加和移除功能
/// Implements CRC16 checksum addition and removal for Modbus RTU protocol
/// <para>
/// CRC16 校验 / CRC16 Checksum:
/// <list type="bullet">
/// <item>多项式0xA001 / Polynomial: 0xA001</item>
/// <item>初始值0xFFFF / Initial value: 0xFFFF</item>
/// <item>2 字节,低字节在前 / 2 bytes, low byte first</item>
/// <item>覆盖从站地址到数据的所有字节 / Covers all bytes from slave address to data</item>
/// </list>
/// </para>
/// <para>
/// 使用示例 / Usage Example:
/// <code>
/// var bytesExtend = new ModbusRtuProtocolLinkerBytesExtend();
///
/// // 扩展 (发送前) / Extend (before sending)
/// byte[] rawData = [0x01, 0x03, 0x00, 0x00, 0x00, 0x0A]; // Modbus 请求
/// byte[] extendedData = bytesExtend.BytesExtend(rawData);
/// // 结果:[0x01, 0x03, 0x00, 0x00, 0x00, 0x0A, 0xC4, 0x0B]
/// // │ CRC16 │
/// ///
/// // 收缩 (接收后) / Reduce (after receiving)
/// byte[] receivedData = [0x01, 0x03, 0x04, 0x00, 0x64, 0x00, 0xC8, 0xB9, 0x0A];
/// byte[] reducedData = bytesExtend.BytesDecact(receivedData);
/// // 结果:[0x01, 0x03, 0x04, 0x00, 0x64, 0x00, 0xC8] // 移除 CRC
/// </code>
/// </para>
/// </remarks>
/// </summary>
public class ModbusRtuProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
{
/// <summary>
/// 协议扩展 (发送前调用) / Protocol Extend (Called Before Sending)
/// <remarks>
/// 在 Modbus RTU 协议数据后添加 CRC16 校验码 (2 字节)
/// Add CRC16 checksum (2 bytes) after Modbus RTU protocol data
/// <para>
/// 处理流程 / Processing Flow:
/// <list type="number">
/// <item>创建新数组,长度 = 原长度 + 2 / Create new array, length = original length + 2</item>
/// <item>计算原始数据的 CRC16 / Calculate CRC16 of original data</item>
/// <item>复制原始数据到新数组 / Copy original data to new array</item>
/// <item>在末尾添加 CRC16 (低字节在前) / Add CRC16 at end (low byte first)</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
/// <param name="content">
/// 扩展前的原始协议内容 / Original Protocol Content Before Extension
/// <remarks>
/// 不包含 CRC 的 Modbus RTU 帧
/// Modbus RTU frame without CRC
/// </remarks>
/// </param>
/// <returns>
/// 扩展后的协议内容 / Extended Protocol Content
/// <remarks>
/// 添加了 CRC16 校验码的完整 RTU 帧
/// Complete RTU frame with CRC16 checksum added
/// </remarks>
/// </returns>
public byte[] BytesExtend(byte[] content)
{
var crc = new byte[2];
// Modbus/RTU 协议扩展,增加 CRC 校验
// Modbus/RTU protocol extension, add CRC checksum
var newFormat = new byte[content.Length + 2];
// 计算 CRC16 / Calculate CRC16
Crc16.GetInstance().GetCRC(content, ref crc);
// 复制原始内容 / Copy original content
Array.Copy(content, 0, newFormat, 0, content.Length);
// 在末尾添加 CRC (低字节在前) / Add CRC at end (low byte first)
Array.Copy(crc, 0, newFormat, newFormat.Length - 2, crc.Length);
return newFormat;
}
/// <summary>
/// 协议收缩 (接收后调用) / Protocol Reduce (Called After Receiving)
/// <remarks>
/// 移除 Modbus RTU 协议数据的 CRC16 校验码 (2 字节)
/// Remove CRC16 checksum (2 bytes) from Modbus RTU protocol data
/// <para>
/// 处理流程 / Processing Flow:
/// <list type="number">
/// <item>创建新数组,长度 = 原长度 - 2 / Create new array, length = original length - 2</item>
/// <item>复制除最后 2 字节外的所有数据 / Copy all data except last 2 bytes</item>
/// <item>返回不含 CRC 的数据 / Return data without CRC</item>
/// </list>
/// </para>
/// <para>
/// 注意 / Note:
/// <list type="bullet">
/// <item>CRC 校验在收缩前已完成 / CRC check is done before reduction</item>
/// <item>此方法仅移除 CRC 字节 / This method only removes CRC bytes</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
/// <param name="content">
/// 收缩前的完整协议内容 / Complete Protocol Content Before Reduction
/// <remarks>
/// 包含 CRC16 校验码的完整 RTU 帧
/// Complete RTU frame with CRC16 checksum
/// </remarks>
/// </param>
/// <returns>
/// 收缩后的协议内容 / Reduced Protocol Content
/// <remarks>
/// 移除 CRC16 校验码后的 Modbus RTU 帧
/// Modbus RTU frame with CRC16 checksum removed
/// </remarks>
/// </returns>
public byte[] BytesDecact(byte[] content)
{
// Modbus/RTU 协议收缩,抛弃最后 2 个字节的内容 (CRC)
// Modbus/RTU protocol reduction, discard last 2 bytes (CRC)
var newContent = new byte[content.Length - 2];
Array.Copy(content, 0, newContent, 0, newContent.Length);
return newContent;
}
}
#endregion
#region ASCII / ASCII Protocol Bytes Extend
/// <summary>
/// Modbus/ASCII 协议字节伸缩 / Modbus/ASCII Protocol Bytes Extend
/// <remarks>
/// 实现 Modbus ASCII 协议的格式转换和 LRC 校验功能
/// Implements format conversion and LRC checksum for Modbus ASCII protocol
/// <para>
/// ASCII 协议格式 / ASCII Protocol Format:
/// <code>
/// : [从站地址][功能码][数据][LRC][CR][LF]
/// │ │ │ │ │ │
/// │ │ │ │ │ └─ 换行符 (0x0A)
/// │ │ │ │ └─ 回车符 (0x0D)
/// │ │ │ └─ LRC 校验 (2 字符十六进制)
/// │ │ └─ 数据 (十六进制 ASCII 字符)
/// │ └─ 功能码 (2 字符十六进制)
/// └─ 起始符 (冒号 0x3A)
/// </code>
/// </para>
/// <para>
/// 编码规则 / Encoding Rules:
/// <list type="bullet">
/// <item>每个字节转换为 2 个十六进制 ASCII 字符 / Each byte converted to 2 hex ASCII characters</item>
/// <item>例如0x1A → "1A" (0x31, 0x41) / e.g., 0x1A → "1A" (0x31, 0x41)</item>
/// <item>LRC 校验:纵向冗余校验 / LRC checksum: Longitudinal Redundancy Check</item>
/// </list>
/// </para>
/// </remarks>
/// </summary>
public class ModbusAsciiProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
{
/// <summary>
/// 协议扩展 (发送前调用) / Protocol Extend (Called Before Sending)
/// <remarks>
/// 将二进制数据转换为 ASCII 格式添加起始符、LRC 校验和结束符
/// Convert binary data to ASCII format, add start marker, LRC checksum and end marker
/// <para>
/// 处理流程 / Processing Flow:
/// <list type="number">
/// <item>添加起始符 ':' (0x3A) / Add start marker ':' (0x3A)</item>
/// <item>将每个字节转换为 2 个十六进制 ASCII 字符 / Convert each byte to 2 hex ASCII characters</item>
/// <item>计算 LRC 校验码并转换为 ASCII / Calculate LRC checksum and convert to ASCII</item>
/// <item>添加结束符 CR LF (0x0D 0x0A) / Add end marker CR LF (0x0D 0x0A)</item>
/// </list>
/// </para>
/// <para>
/// 示例 / Example:
/// <code>
/// 原始数据 / Raw data: [0x01, 0x03, 0x00, 0x00]
/// 扩展后 / Extended: [0x3A, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, LRC, 0x0D, 0x0A]
/// ASCII: ":01030000[LRC][CR][LF]"
/// </code>
/// </para>
/// </remarks>
/// </summary>
/// <param name="content">
/// 扩展前的原始协议内容 / Original Protocol Content Before Extension
/// <remarks>
/// 二进制格式的 Modbus 数据
/// Binary format Modbus data
/// </remarks>
/// </param>
/// <returns>
/// 扩展后的协议内容 / Extended Protocol Content
/// <remarks>
/// ASCII 格式的完整帧
/// Complete frame in ASCII format
/// </remarks>
/// </returns>
public byte[] BytesExtend(byte[] content)
{
// Modbus/ASCII 协议扩张,前面增加:,后面增加 LRC 校验和尾字符
// Modbus/ASCII protocol extension, add ':' at front, LRC and tail characters at end
var newContent = new List<byte>();
// 添加起始符 ':' / Add start marker ':'
newContent.AddRange(Encoding.ASCII.GetBytes(":"));
// 将每个字节转换为 2 个十六进制 ASCII 字符 / Convert each byte to 2 hex ASCII characters
foreach (var number in content)
newContent.AddRange(Encoding.ASCII.GetBytes(number.ToString("X2")));
// 计算并添加 LRC 校验 / Calculate and add LRC checksum
newContent.AddRange(Encoding.ASCII.GetBytes(Crc16.GetInstance().GetLRC(content)));
// 添加结束符 CR LF / Add end marker CR LF
newContent.Add(0x0d);
newContent.Add(0x0a);
return newContent.ToArray();
}
/// <summary>
/// 协议收缩 (接收后调用) / Protocol Reduce (Called After Receiving)
/// <remarks>
/// 将 ASCII 格式数据转换回二进制格式移除起始符、LRC 校验和结束符
/// Convert ASCII format data back to binary format, remove start marker, LRC checksum and end marker
/// <para>
/// 处理流程 / Processing Flow:
/// <list type="number">
/// <item>转换为字符串 / Convert to string</item>
/// <item>查找换行符位置 / Find newline position</item>
/// <item>移除起始符 ':' 和结束符 CRLF / Remove start marker ':' and end marker CRLF</item>
/// <item>每 2 个字符解析为一个字节 / Parse every 2 characters as one byte</item>
/// <item>移除 LRC 校验字节 / Remove LRC checksum byte</item>
/// </list>
/// </para>
/// <para>
/// 示例 / Example:
/// <code>
/// ASCII: ":01030000000AF8[CR][LF]"
/// 移除头尾 / Remove head and tail: "01030000000AF8"
/// 解析字节 / Parse bytes: [0x01, 0x03, 0x00, 0x00, 0x00, 0x0A, 0xF8]
/// 移除 LRC / Remove LRC: [0x01, 0x03, 0x00, 0x00, 0x00, 0x0A]
/// </code>
/// </para>
/// </remarks>
/// </summary>
/// <param name="content">
/// 收缩前的完整协议内容 / Complete Protocol Content Before Reduction
/// <remarks>
/// ASCII 格式的完整帧
/// Complete frame in ASCII format
/// </remarks>
/// </param>
/// <returns>
/// 收缩后的协议内容 / Reduced Protocol Content
/// <remarks>
/// 二进制格式的 Modbus 数据
/// Binary format Modbus data
/// </remarks>
/// </returns>
public byte[] BytesDecact(byte[] content)
{
// Modbus/ASCII 协议收缩,抛弃头尾
// Modbus/ASCII protocol reduction, discard head and tail
var newContent = new List<byte>();
var ans = Encoding.ASCII.GetString(content);
// 查找换行符位置 / Find newline position
var index = ans.IndexOf(Environment.NewLine);
// 移除起始符 ':' 和结束符 CRLF / Remove start marker ':' and end marker CRLF
ans = ans.Substring(1, index - 1);
// 每 2 个字符解析为一个字节 / Parse every 2 characters as one byte
for (var i = 0; i < ans.Length; i += 2)
{
var number = byte.Parse(ans.Substring(i, 2), NumberStyles.HexNumber);
newContent.Add(number);
}
// 移除最后一个字节 (LRC 校验) / Remove last byte (LRC checksum)
newContent.RemoveAt(newContent.Count - 1);
return newContent.ToArray();
}
}
#endregion
/// <summary>
/// Modbus RTU 协议接收器字节伸缩 / Modbus RTU Protocol Receiver Bytes Extend
/// <remarks>
/// 继承自 ModbusRtuProtocolLinkerBytesExtend用于服务器端
/// Inherits from ModbusRtuProtocolLinkerBytesExtend, for server-side use
/// </remarks>
/// </summary>
public class ModbusRtuProtocolReceiverBytesExtend : ModbusRtuProtocolLinkerBytesExtend
{
// 使用 RTU 协议的字节伸缩方法 / Use RTU protocol bytes extend methods
}
}