DotNetty 实现 Modbus TCP 系列 (一) 报文类
本文已收录至:开源 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 系列 (一) 报文类的更多相关文章
- DotNetty 实现 Modbus TCP 系列 (二) ModbusFunction 类图及继承举例
本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议 ModbusFunction 类图如下: 如前文所述,所有请求/相应的 PDU 均继承自 ModbusFunction, ...
- DotNetty 实现 Modbus TCP 系列 (三) Codecs & Handler
本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议 DotNetty 作为一个半成品,我们不需要关注细节的实现,只需要关注自己的业务即可,所以最主要的就是处理 Codecs ...
- DotNetty 实现 Modbus TCP 系列 (四) Client & Server
本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议 Client public class ModbusClient { public string Ip { get; } ...
- 开源 DotNetty 实现的 Modbus TCP/IP 协议
本项目的目的是为了学习 DotNetty 与 Modbus 协议,参考 modjn 实现功能 0x01: Read Coils (读取线圈/离散量输出状态) 0x02: Read Discrete I ...
- 【.NET6+Modbus】Modbus TCP协议解析、仿真环境以及基于.NET实现基础通信
前言:随着工业化的发展,目前越来越多的开发,从互联网走向传统行业.其中,工业领域也是其中之一,包括各大厂也都在陆陆续续加入工业4.0的进程当中. 工业领域,最核心的基础设施,应该是与下位硬件设备或程序 ...
- 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 ...
- Modbus TCP 示例报文
调试modbus tcp 整理百度文库文档如下 <modbus-tcp-报文举例分析> <MODBUSTCP通讯报文> Client request: 19 B2 00 00 ...
- C#ModBus Tcp 报文解析
上一篇博客已经完成 C#ModBus Tcp Master的实现 本篇主要对不同的功能码所发出的报文进行解析(包括请求报文及响应报文) 读操作 功能码 0x01 读一组线圈 读取站号为1 从地址12开 ...
- 开放型Modbus/TCP 规范
修订版 1.0,1999 年3 月29 日Andy SwalesSchneider 电气公司aswales@modicon.com目录目录............................... ...
随机推荐
- linux安装mysql5.7.19
0.查看操作系统内核版本 cat /proc/version [admin@octopus-att-d-030098 ~]$ cat /proc/versionLinux version 3.10.0 ...
- linux安装jdk1.8(rpm方式)
在Oracle官网下载64位的jdk1.8版本 jdk1.8: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloa ...
- KNN-笔记(1)
1 - 背景 KNN:k近邻,表示基于k个最近的邻居的一种机器学习方法.该方法原理简单,构造方便.且是一个非参数化模型. KNN是一个"懒学习"方法,也就是其本身没有训练过程.只有 ...
- 多个jdk 变更 引起 tomcat插件 启动不了 The JRE could not be found.Edit the server and change the JRE location.
The JRE could not be found.Edit the server and change the JRE location. 在Windows->Preferences-> ...
- Rommel - C# 浅谈 接口(Interface)的作用
鉴于网上太多太多的对C# 接口的误解,想来想去还是自己做一个完美的接口 篇章 继承"基类"跟继承"接口"都能实现某些相同的功能,但有些接口能够完成的功能是只用基 ...
- 关于VS2017 添加 EF的MVC控制器报错的解决方法
1. 错误描述 :no database provider has been configured fot this DbContext. 此类错误是上下文的注册造成的.解决方式在DBContext中 ...
- python 跨域处理方式
因为浏览器的同源策略限制,不是同源的脚本不能操作其他源下面的资源,想操作另一个源下面的资源就属于跨域了,这里说的跨域是广义跨域,我们常说的代码中请求跨域,是狭义的跨域,即在脚本代码中向非同源域发送ht ...
- 三、临时弹出一个QQ对话窗口
第一种:需要添加好友才可以访问 <a href="http://wpa.qq.com/msgrd?v=3&uin=317985559&site=qq&menu= ...
- 【RSYSLOG】The Property Replacer【转】
最近在调整日志平台的日志格式,一下是RSYSLOG的 Property Replacer 说明.鉴于RSYSLOG官网略坑,转发一下,原地址忘记了- - ||| The property replac ...
- ios 后台下载,断点续传总结
2018年12月05日 16:09:00 weixin_34101784 阅读数:5 https://blog.csdn.net/weixin_34101784/article/details/875 ...