本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议

Modbus TCP/IP 报文

  • 报文最大长度为 260 byte (ADU = 7 byte MBAP Header + 253 byte PDU)
  • Length = Unit Identifier 长度 + PDU 长度

MBAP Header

PDU

PDU 由两部分构成:Function Code(功能码) 和 Data 组成

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

DotNetty 实现 Modbus TCP 系列 (一) 报文类的更多相关文章

  1. DotNetty 实现 Modbus TCP 系列 (二) ModbusFunction 类图及继承举例

    本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议 ModbusFunction 类图如下: 如前文所述,所有请求/相应的 PDU 均继承自 ModbusFunction, ...

  2. DotNetty 实现 Modbus TCP 系列 (三) Codecs & Handler

    本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议 DotNetty 作为一个半成品,我们不需要关注细节的实现,只需要关注自己的业务即可,所以最主要的就是处理 Codecs ...

  3. DotNetty 实现 Modbus TCP 系列 (四) Client & Server

    本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议 Client public class ModbusClient { public string Ip { get; } ...

  4. 开源 DotNetty 实现的 Modbus TCP/IP 协议

    本项目的目的是为了学习 DotNetty 与 Modbus 协议,参考 modjn 实现功能 0x01: Read Coils (读取线圈/离散量输出状态) 0x02: Read Discrete I ...

  5. 【.NET6+Modbus】Modbus TCP协议解析、仿真环境以及基于.NET实现基础通信

    前言:随着工业化的发展,目前越来越多的开发,从互联网走向传统行业.其中,工业领域也是其中之一,包括各大厂也都在陆陆续续加入工业4.0的进程当中. 工业领域,最核心的基础设施,应该是与下位硬件设备或程序 ...

  6. modbus tcp数据报文结构

    modbus tcp数据报文结构 请求:00 00 00 00 00 06 09 03 00 00 00 01 响应:00 00 00 00 00 05 09 03 02 12 34 一次modbus ...

  7. Modbus TCP 示例报文

    调试modbus  tcp 整理百度文库文档如下 <modbus-tcp-报文举例分析> <MODBUSTCP通讯报文> Client request: 19 B2 00 00 ...

  8. C#ModBus Tcp 报文解析

    上一篇博客已经完成 C#ModBus Tcp Master的实现 本篇主要对不同的功能码所发出的报文进行解析(包括请求报文及响应报文) 读操作 功能码 0x01 读一组线圈 读取站号为1 从地址12开 ...

  9. 开放型Modbus/TCP 规范

    修订版 1.0,1999 年3 月29 日Andy SwalesSchneider 电气公司aswales@modicon.com目录目录............................... ...

随机推荐

  1. odoo8 和odoo10区别

    V8  函数:'sale_order_count': fields.function(_sale_order_count, string='# of Sales Order', type='integ ...

  2. hibernate(*.hbm.xml)中新添加的字段被标记为红色(找不到)的解决方法

    首先得是以这个方式生成的bean和xml,配置好了数据源(这样才能让hibernate中的配置和mysql进行交互) https://www.cnblogs.com/kinome/p/10549969 ...

  3. Java执行JavaScript脚本破解encodeInp()加密

    一:背景 在模拟登录某网站时遇到了用户名和密码被JS进行加密提交的问题,如图: 二:解决方法 1.我们首先需要获得该JS加密函数,一般如下: conwork.js var keyStr = " ...

  4. 撒花!中文翻译仓库链接已加入 ML.NET 官方示例网站首页

    从2018年12月02日决定开始做ML.NET 示例中文版https://github.com/feiyun0112/machinelearning-samples.zh-cn,然后以每天一篇的速度进 ...

  5. python 操作数据库

    官方文档:https://www.python.org/dev/peps/pep-0249/ 1.创建connection,建立网络连接 MySQLdb.Connect(host,port,user, ...

  6. 容器互联(linking)

    容器互联(linking)是一种让多个容器中的应用进行快速交互的方式. 它会在源和接受容器中间创建连接关系,接受容器可以通过容器名快速访问到源容器而不用指出具体的IP地址.

  7. 牛客国庆集训派对Day2

    题目链接:https://www.nowcoder.com/acm/contest/202/A A 题意:给出最大4096*64和64*4096的矩阵,其中有一个矩阵只含有0和1,问你它们相乘所得到得 ...

  8. c++ 入门之对象指针

    我们想 像使用基本数据类型一样使用类,自然,类自然也有指针,我们通过下面的代码来领教一下对象指针存在的意义: # include "iostream" # include &quo ...

  9. ElastichSearch漏洞

    Ubuntu服务器被黑经历(ElastichSearch漏洞) 起因 最近我们的一台Ubuntu阿里云服务器一直提示有肉鸡行为,提示了好几天,开始并没有关注,然后连续几天后发现应该是个大问题啊.很可能 ...

  10. semantic-ui 标题

    在semantic-ui中定义了5中标题样式,注意HTML中有h1-h6,而semantic-ui中只有h1-h5. 不过需要注意的是,semantic-ui的标题仍旧使用h1-h5来表示,但是在cl ...