zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    利用jmSlip写一个移动端顶部日历选择组件
    JS写的排序算法演示
    jmSlip WEB前端滑屏组件
    如何:使用 Visual Basic 编写基于 Unity3D 的计算器
    验证 .NET 4.6 的 SIMD 硬件加速支持的重要性
    VB 2015 的 闭包(Closure)
    VS "15" 预览 5 中 VB 15 新增的功能
    演练:使用Xamarin.Forms开发产品介绍性质的应用(VB版)
    UWP游戏防内存修改器的方法
    优化win2d实现的萤火虫粒子效果
  • 原文地址:https://www.cnblogs.com/victorbu/p/10369919.html
Copyright © 2011-2022 走看看