DotNetty 實現 Modbus TCP 系列 (一) 報文類


本文已收錄至:開源 DotNetty 實現的 Modbus TCP/IP 協議

Modbus TCP/IP 報文

ADU

  • 報文最大長度為 260 byte (ADU = 7 byte MBAP Header + 253 byte PDU)
  • Length = Unit Identifier 長度 + PDU 長度

MBAP Header

Header

PDU

PDU 由兩部分構成:Function Code(功能碼) 和 Data 組成

Function Code

部分功能碼:

Function Code

報文類

ModbusHeader

public class ModbusHeader
{
	public ushort TransactionIdentifier { get; set; }
	public ushort ProtocolIdentifier { get; set; }
	public ushort Length { get; set; }
	public short UnitIdentifier { get; set; }

	public ModbusHeader(IByteBuffer buffer)
	{
		TransactionIdentifier = buffer.ReadUnsignedShort();
		ProtocolIdentifier = buffer.ReadUnsignedShort();
		Length = buffer.ReadUnsignedShort();
		UnitIdentifier = buffer.ReadByte();
	}

	public ModbusHeader(ushort transactionIdentifier, short unitIdentifier)
		: this(transactionIdentifier, 0x0000, unitIdentifier) // for modbus protocol: Protocol Identifier = 0x00
	{

	}

	private ModbusHeader(ushort transactionIdentifier, ushort protocolIdentifier, short unitIdentifier)
	{
		TransactionIdentifier = transactionIdentifier;
		ProtocolIdentifier = protocolIdentifier;
		UnitIdentifier = unitIdentifier;
	}

	public IByteBuffer Encode()
	{
		IByteBuffer buffer = Unpooled.Buffer();

		buffer.WriteUnsignedShort(TransactionIdentifier);
		buffer.WriteUnsignedShort(ProtocolIdentifier);
		buffer.WriteUnsignedShort(Length);
		buffer.WriteByte(UnitIdentifier);

		return buffer;
	}
}

ModbusHeader 對應 MBAP Header,包含兩個構造函數:第一個構造函數用於從緩沖區解析消息頭,第二個構造函數用來請求/響應時手動構造消息頭。Encode 方法用於在傳輸前對消息頭進行編碼。

ModbusFunction

public abstract class ModbusFunction
{
	protected short FunctionCode { get; }

	protected ModbusFunction(short functionCode)
	{
		FunctionCode = functionCode;
	}
	/// <summary>
	/// PDU length -1 (not include function code length)
	/// </summary>
	/// <returns></returns>
	public abstract int CalculateLength();   

	public abstract void Decode(IByteBuffer buffer);

	public abstract IByteBuffer Encode();

}

ModbusFunction 對應 PDU,該類為抽象類,所有的請求/相應的 PDU 均繼承自該類。實際使用中根據 FunctionCode 實例化具體的子類對象。其中 CalculateLength 方法用來計算 Data 部分的長度,Decode 方法用於從緩沖區解析 Data,Encode 方法用於在傳輸前對 Data 編碼。

ModbusFrame

public class ModbusFrame
{
	public ModbusHeader Header { get; set; }
	public ModbusFunction Function { get; set; }

	public ModbusFrame(ModbusHeader header, ModbusFunction function)
	{
		Header = header;
		Function = function;
	}

	public IByteBuffer Encode()
	{
		Header.Length = (ushort)(1 + 1 + Function.CalculateLength());// Unit Identifier + Function Code + data length

		IByteBuffer buffer = Unpooled.Buffer();

		buffer.WriteBytes(Header.Encode());
		buffer.WriteBytes(Function.Encode());

		return buffer;
	}
}

ModbusFrame 對應 ADU。Encode 方法用於在傳輸前對 ADU 編碼。

開源地址:modbus-tcp


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM