青岛建站合作/网站查询服务器

1 引言
1.1 范围
这个文件的范围是介绍 TCP/IP 上的 MODBUS 报文传输服务,提供参考信息以帮助软件开发者使用这种服务。这个文中不包括 MODBUS 功能码的编码相关内容,这些信息请参阅 :
曾小庆:一、MODBUS通讯协议完整介绍(全文10000字以上)zhuanlan.zhihu.com

这个文件准确而全面地描述了 MODBUS 报文传输服务的实现。其目的是便于在那些使用 MODBUS 报文传输服务的设备之间进行可互操作。
这个文件主要由三部分组成:
(1)在 TCP/IP 上的 MODBUS 协议概述
(2)MODBUS 客户机、服务器和网关工具的功能描述
(3)针对一个 MODBUS 实现实例的目标模型建议的实现准则。
1.2 客户机/服务器模型
MODBUS 报文传输服务提供设备之间的客户机/服务器通信,这些设备联接在一个 Ethernet(以太网) TCP/IP 网络上。
这个客户机/服务器模式是基于 4 种类型报文:
#MODBUS 请求
#MODBUS 证实
#MODBUS 指示
#MODBUS 响应

MODBUS 请求是客户机在网络上发送用来启动事务处理的报文
MODBUS 指示是服务端接收的请求报文
MODBUS 响应是服务器发送的响应信息
MODBUS 证实是在客户端接收的响应信息
MODBUS 报文传输服务(客户机/服务器模型)用于实时信息交换:
(1)在两个设备应用程序之间
(2)在设备应用和其它设备之间
(3)在 HMI/SCADA 应用程序和设备之间
(4)在一个 PC 和一个提供在线服务的设备程序之间
2 缩略语
ADU 应用数据单元
IETF 因特网工程工作组
IP 互连网协议
MAC 介质访问控制
MB MODBUS
MBAP MODBUS 协议
PDU 协议数据单元
PLC 可编程序逻辑控制器
TCP 传输控制协议
BSD 伯克利软件分配
MSL 最大段寿命
3 背景概要
3.1 协议描述
3.1.1 总体通信结构
MODBUS TCP/IP 的通信系统可以包括不同类型的设备:
(1)连接至 TCP/IP 网络的 MODBUS TCP/IP 客户机和服务器设备;
(2)互连设备,例如:在 TCP/IP 网络和串行链路子网之间互连的网桥、路由器或网关,联接,该子网允许将 MODBUS 串行链路客户机和服务器终端设备连接起来。

MODBUS 协议定义了一个与基础通信层无关的简单协议数据单元(PDU)。特定总线或网络上的 MODBUS 协议映射能够在应用数据单元(ADU)上引入一些附加域。

启动 MODBUS 事务处理的客户机建立 MODBUS 应用数据单元。这个功能码向服务器指示执行执行哪种操作。
3.1.2 TCP/IP 上的 MODBUS 应用数据单元
这节描述了 MODBUS TCP/IP 网络中进行的 MODBUS 请求或响应的封装。

在 TCP/IP 上使用一种专用报文头识别 MODBUS 应用数据单元。将这种报文头称为 MBAP 报文头(MODBUS 协议报文头)。
这种报文头提供一些与串行链路上使用的 MODBUS RTU 应用数据单元比较的差别:
(1)用MBAP 报文头中的单个字节单元标识符取代MODBUS串行链路上通常使用的MODBUS从地址域。这个单元标识符用于设备的通信,这些设备使用单个 IP 地址支持多个独立 MODBUS 终端单元,例如:网桥、路由器和网关。
(2)用接收者可以验证完成报文的方式设计所有 MODBUS 请求和响应。对于 MODBUS PDU有固定长度的功能码来说,仅功能码就足够了。对于在请求或响应中携带一个可变数据的功能码来说,数据域包括字节数。
(3)当在 TCP 上携带 MODBUS 时,即使将报文分成多个信息包来传输,办事在 MBAP 报文头上携带附加长度信息,以便接收者能识别报文边界。显式和隐式长度规则的存在以及 CRC-32 差错校验码的使用(在以太网上)将对请求或响应报文产生极小的未检出干扰。
3.1.3 MBAP 报文头描述
MBAP 报文头包括下列域:

报文头为 7 个字节长:
事务处理标识符:用于事务处理配对。在响应中,MODBUS 服务器复制请求的事务处理标识符。
协议标识符:用于系统内的多路复用。通过值 0 识别 MODBUS 协议。
长度:长度域是下一个域的字节数,包括单元标识符和数据域。
单元标识符:为了系统内路由,使用这个域。专门用于通过以太网 TCP-IP 网络和 MODBUS 串行链路之间的网关对 MODBUS 或 MODBUS+串行链路从站的通信。MODBUS 客户机在请求中设置这个域,在响应中服务器必须利用相同的值返回这个域。
在注册的 502 端口上利用 TCP 发送所有 MODBUS/TCP ADU。
注:用 Big-endian 编码不同域。
3.2 MODBUS 功能码描述
曾小庆:一、MODBUS通讯协议完整介绍(全文10000字以上)zhuanlan.zhihu.com
4 功能描述
这里提供的 MODBUS 组件结构是一个既包含 MODBUS 客户机又包含 MODBUS 服务器组件的通用模型,适用于任何设备。
有些设备可能仅提供服务器或客户机组件。
4.1 MODBUS 组件结构模型

通信应用层
一个 MODBUS 设备可以提供一个客户机和/或服务器 MODBUS 接口。
可提供一个 MODBUS 后台接口,允许间接的访问用户应用对象。
此接口由四部分组成:离散量输入、离散量输出(线圈)、寄存器输入和寄存器输出。此接口与用户应用数据之间的映射必须加以定义(本地问题)。


(1)MODBUS 客户机
MODBUS 客户机允许用户应用清晰地控制与远端设备的信息交换。MODBUS 客户机根据用户应用向 MODBUS 客户接口发送的需求中所包含的参数生成一个 MODBUS 请求。
MODBUS 客户机调用一个 MODBUS 的事务处理,事务处理管理包括 MODBUS 证实的等待和处理。
(2)MODBUS 客户机接口
MODBUS 客户机接口提供一个接口,使得用户应用能够生成对包括访问 MODBUS 应用对象在内的各类 MODBUS 服务的请求。尽管在实现模型中以实例说明,但是 MODBUS 客户机接口(API)在这里不进行描述。
(3)MODBUS 服务器
在收到一个 MODBUS 请求以后,模块激活一个本地操作进行读、写、或完成其他操作。这些操作的处理对应用程序开发人员来说都是透明的。MODBUS 服务器的主要功能是等待来自 TCP502 口的 MODBUS 请求,处理这一请求,然后生成一个 MODBUS 应答,应答取决于设备状况(场境)。
(4)MODBUS 后台接口
MODBUS 后台接口是一个从 MODBUS 服务器到定义应用对象的用户应用之间的接口。
TCP 管理层
报文传输服务的主要功能之一是管理通信的建立和结束,管理建立在 TCP 连接上的数据流。
(1)连接管理
在客户机和服务器的 MODBUS 模块之间的通信需要调用 TCP 连接管理模块。它负责全面管理报文传输 TCP 连接。
连接管理中存在两种可能:用户应用自身管理 TCP 连接,或全部由这个模块进行连接管理,而对用户应用透明。后一种方案灵活性较差。
TCP 502 口的侦听是为 MODBUS 通信保留的。在缺省状态下,强制侦听这个口。然而,有些市场或应用可能需要其他口作为 TCP 上 MODBUS 的通信之用。当需要与非施奈德(Schneider)产品进行互操作时,就属于这种情况,例如:在建筑控制中。为此,强烈建议:客户机和服务器均应向用户提供对 TCP 口号上的 MODBUS 参数进行配置的可能性。重要的是:即使在某一个特定的应用中为 MODBUS 服务配置了其他 TCP 服务器口,除一些特定应用口外,TCP 服务器 502 口必须仍然是可用的。
(2)访问控制模块
在某些至关重要的场合,必须禁止不需要的主机对设备内部数据的访问。这既是为什么需要安全模式,也是在需要时实现安全处理的原因。
TCP/IP 栈层
TCP/IP 的栈可以进行参数配置,以便于使得数据流控制、地址管理和连接管理适应于特定的产品或系统的不同的约束。一般说来,BSD 套接字接口就用来管理 TCP 连接。
资源管理和数据流控制
为了平衡 MODBUS 客户机与服务器之间进出报文传输的数据流,在 MODBUS 报文传输栈的所有各层均设置了数据流控制机制。资源管理和数据流控制模块首先是基于 TCP 内部数据流控制,附加数据链路层的某些数据流控制,以及用户应用层的数据流控制。
4.2 TCP 连接管理
4.2.1 连接管理模块
4.2.1.1 总体描述
MODBUS 通信需要建立客户机与服务器之间的 TCP 连接。
连接的建立可以由用户应用模块直接实现,也可以由 TCP 连接管理模块自动完成。
在第一种情况下,用户应用模块必须提供应用程序接口,以便完全管理连接。这种方式为应用开发人员提供了灵活性,但需要 TCP/IP 机制方面的专长。
在第二种方案中,TCP 连接管理完全不出现,用户应用仅需要发送和接受 MODBUS 报文。TCP 连接管理模块负责在需要时建立新的 TCP 连接。
TCP 客户机和服务器连接数量的定义不属于本文件的范畴(在本文中采用 n)。根据设备能力, TCP 连接的数量会不同。
实现规则:
1)如果没有明确的用户需求,建议采用自动的 TCP 连接管理;
2)建议:打开并保持与远端设备的连接,而不要在每次 MODBUS/TCP 事务处理时打开和关闭连接。
注:然而,MODBUS 客户必须能够接收来自服务器的关闭请求,并关闭连接。当需要时,连接可以 被重新打开。
3)建议:每一个 MODBUS 客户至少要打开与远端 MODBUS 服务器的 TCP 连接(同一 IP 地址)。一个应用建立一个连接是好的选择。
4)几个 MODBUS 事务处理可以在同一个 TCP 连接上被同时激活
注:如果以此方式,MODBUS 事务处理标识必须被用来唯一地识别请求与响应的匹配。
5)在两个远端 MODBUS 设备(一个客户机和一个服务器)之间双向通信的情况下,有必要为客户机 数据流和服务器数据流分别建立连接。
6)一个 TCP 帧只能传送一个 MODBUS ADU。建议:不要在同一个 TCP PDU 中发送多个请求或应答。

1) 显式 TCP 连接管理
用户应用模块负责管理所有的 TCP 连接:主动的和被动的连接建立、连接结束………。对 客户机与服务器间所有的连接进行这种管理。BSD 套接字接口用在用户应用模块中来管理 TCP 连接。这种方案提供了完全的灵活性,但也意味着应用开发人员要具备充分的有关 TCP 的知识。
考虑到设备的能力和需求,必须进行配置客户机与服务器间连接数的限制。
2) 自动 TCP 连接管理
TCP 连接管理对用户应用模块是完全透明的。连接管理模块可以接受足够数量的客户机/服 务器连接。否则,在超过所授权数量的连接时必须有一种实现机制。在这种情况下,我们建议: 关闭最早建立的不使用的连接。
在收到第一个来自远端客户机或本地用户应用的数据包后,就建立了与远端对象的连接。 如果一个网络进行终止或本地设备决定终止,此连接将被关闭。在接收连接请求时,访问控制 选项可用来禁止未授权客户访问设备的可能性。
TCP 连接管理模块采用栈接口(通常 BSD 套接字接口)来与 TCP/IP 栈进行通信。
为了保持系统需求与服务器资源之间的兼容,TCP 管理将保持两个连接库。
#第一个库(优先连接库)由那些从不被本地主动关闭的连接组成。必须提供一个配置来建立这个库。实现的原理是将这个库的每一个可能的连接与一个特定的 IP 地址联系起来。具有这个 IP 地址的设备被称为“标记的”。任何一个被“标记的”设备的新的连接请求必须被接收,并从优先连接库中取出。还有必要设置允许每个远端设备最多建立连接的数量,以避免同一设备使用优先连接库中所有的连接。
#第二个库(非优先连接库)包括了非标记设备的连接。这里采用的规则是:当有来自非标记设备的新的连接请求,以及库中没有连接可用时,关闭早些时候建立的连接。
一个配置可作为选项提供来分配每个库中可用连接的数量。然而(非强制性的),如果需要,设计人员可在设计期间设定连接的数量。
4.2.1.2 连接管理描述
连接建立
MODBUS 报文传输服务必须在 502 口上提供一个侦听套接字,允许接收新的连接和与其他设备交换数据。
当报文传输服务需要与远端服务器交换数据时,它必须与远端 502 口建立一个新的客户连接,以便与远距离交换数据。本地口必须高于 1024,并且每个客户连接各不相同。

如果客户机与服务器的连接数量大于授权的连接数量,则最早建立的无用的连接被关闭。激活 访问控制机制检查远端客户机的 IP 地址是否是经过授权的。如果未经授权,将拒绝新的连接。
MODBUS 数据变换
基于已经打开的正确的 TCP 连接发送 MODBUS 请求。远端设备的 IP 地址用于寻找所建的 TCP 连 接。在与同一个远端设备建立多个连接时,必须选择其中一个连接用于发送 MODBUS 报文,可以采取 不同的选择策略,例如:最早的连接、第一个连接。在 MODBUS 通信的全过程中,连接必须始终保持 打开。如同下列各章所描述的一样,一个客户机可以向一个服务器启动多个事务处理,而不必等待 前序事物处理结束。
连接关闭
当客户机与服务器间的 MODBUS 通信结束时,客户机必须关闭用于通信的连接。
4.2.2 操作模式对 TCP 连接的影响
某些操作模式(两操作端点之间通信断开、一个端点的故障和重新启动、………)会对 TCP 连接产生影响。一个连接可被视为在这一侧关闭或异常终止而没有另一侧的确认,称这种连接为“半打开”的连接。
本章描述每种主要操作模式的特性。假设在连接的两端采用了“保持连接”TCP 机制。
4.2.2.1 两操作端之间通信断开
通信断开的原因可以是服务器侧以太网连接电缆断开。预期的特性是:
· 如果在连接上没有正在发送数据包:
如果通信断开持续的时间短于“保持连接”计时器的值,将察觉不到通信断开。如果通信断开时间超过“保持连接”计时器的值,将一个错误返回到 TCP 连接层,由其复位连接。
· 如果在连接断开的前后发送一些数据包:
TCP 重新传输算法(Jacobson 算法、Karn 算法以及指数补偿算法,参见第 4.3.2 节)被激活。这可能导致在“保持连接”计时器终止之前 TCP 栈连接层复位。
4.2.2.2 服务器端的故障和重新启动
在服务器故障和重新启动以后,客户端处于“半打开”连接状态。预期的特性是:
· 如果在半打开的连接上没有发送数据包:
只要“保持连接”计时器还在计时中,从客户端看,连接是半打开的。之后,将返回一个错误到 TCP 管理层,由其复位连接。
· 如果在半打开的连接上发送一些数据包:
服务器在不存在的连接上接收数据。TCP 层的栈发送一个复位指令来关闭客户端的半打开的连接。
4.2.2.3 客户机端的故障和重新启动
在客户机故障和重新启动以后,服务器侧处于“半打开”连接状态。预期的状态是:
· 如果在半打开的连接上没有发送数据包:
只要“保持连接”计时器还在计时中,从服务器端看,这种连接是半打开的。之后,将返回一个错误到 TCP 管理层,由其复位连接。
· 如果在“保持连接”计时器完成计时前,客户机打开一个新的连接:
必须分两种情况研究:
1) 所打开的连接与服务器侧半打开的连接具有相同的特性(相同的源和目的口、相同的源和目的 IP 地址),所以,在连接建立超时后(伯克利实现的多数情况下为 75ms),TCP 栈层将不能打开连接。为了避免较长超时时间内不能进行通信,建议:在客户机端重新启动后,确保使用与原有连接不同的源口号建立连接。
2) 所打开的连接与服务器侧半打开的连接具有不同的特性(不同的源口和相同的目的口、相同的源和目的 IP 地址),所以,在 TCP 栈层上打开连接,并向服务器侧的 TCP 管理层发送信号。
如果服务器侧 TCP 管理层仅支持一个远端客户机 IP 地址的连接,那么可以关闭原来的半打开的连接,使用新的连接。
如果服务器侧 TCP 管理层支持多个远端客户机 IP 地址的连接,那么新的连接保持打开状态,原来的连接也保持半打开状态,直到“保持连接”计时器计时结束,此时,将返回一个错误到 TCP 管理层。之后,TCP 管理层将能够复位原有的连接。
4.2.3 访问控制模块
这个模块的目的是检查每一个新的连接,对照一个合法授权的远程 IP 地址列表,它可以授权或禁止一个远端客户机的 TCP 连接。
在至关重要的场合,应用开发人员需要选择访问控制模块来保证网络的访问。在这种情况下,需要对每个远端 IP 授权或禁止访问。用户需提供一个 IP 地址的列表,并特别注明每个 IP 地址是否合法授权。在缺省情况下,在安全模式中,用户未配置的 IP 地址均被禁止。所以,借助于访问控制模式,关闭来自未知的 IP 地址的访问连接。
4.3 TCP/IP 栈的使用
TCP/IP 栈提供了一个接口,用来管理连接、发送和接收数据,还可以进行参数配置,以使得栈的特性适应于设备或系统的限制。

本章的目的是给出有关栈接口的综述,以及一些与栈的参数配置有关的信息。总揽综述主要是 MODBUS 报文传输所使用的一些特性。
对于更多的信息,建议阅读 RFC 1122,这个 RFC 1122 为厂商和开发商提供了互联网通信软件的指南。RFC 1122 详述了一个连接到互联网的主机必须采用的标准协议,以及一组明确的需求和选项。
栈接口一般是基于本文件中描述的 BSD(伯克利软件分配代码)接口。
4.3.1 BSD 套接字接口的应用
注:有些 TCP/IP 栈从性能考虑提出其他类型的接口。MODBUS 客户机或服务器可以使用这些特定的接口,但是在本文件中对这种使用不做描述。
一个套接字是一个通信端点,它是通信中的基本构成块。通过套接字发送和接收数据可以执行一个 MODBUS 通信。TCO/IP 库仅提供了使用 TCP 和提供基于连接的通信服务的流套接字。
socket()函数用来创建套接字。返回的一个套接字号被创建者用来访问套接字。套接字创建时没有地址(IP 地址和口号)。直到一个口被绑定到该套接字时,方可接收数据。
bind()函数用来绑定一个口号到套接字。bind()函数在套接字与所指定的口号之间建立一个连接。
为了初始化一个连接,客户端必须发送 connect()函数来指定套接字号、远端 IP 地址和远端侦听口号(主动连接建立)。
为了完成连接,服务器端必须发送 accept()函数指定以前在 listen()调用中所指定的套接字号(被动连接建立)。一个新的套接字被创建,并具有与最初相同的特性。这个新的套接字连接到客户机的套接字,而将套接字号返回到服务器端。于是,释放初始套接字,以便为其他欲与服务器连接的客户机使用。
在 TCP 连接建立以后,数据即可被传递。将 Send()和 recv()函数专门地设计成与已经连接的套接字一道使用。
setsockopt()函数允许套接字的创建者用套接字建立若干选项。这些选项描述了套接字的操作特征。在第 4.3.2 节中给出这些选项的描述。
select()函数允许编程人员测试所有套接字上的事件。
shutdown()函数允许套接字的使用者来终止 send()和/或 recv()。
一旦不再需要套接字,可以使用 close()函数来放弃套接字的描述信息。

上图给出了客户机与服务器间的完整的 MODBUS 通信过程。客户机建立一个连接,向服务器发送 3 个 MODBUS 请求,而不等待第一个请求的应答到来。在收到所有的应答后,客户机正常地关闭连接。
4.3.2 TCP 层参数配置
可以调整 TCP/IP 栈的一些参数以使得其特性满足产品或系统的限制。TCP 层的下列参数可以进行调整:
每个连接的参数
SO-RCVBUF, SO-SNDBUF:
这些参数允许为发送和接收用套接字接口设定高限位。可以通过调整这些参数来实现流量控制管理。接收缓存区的的大小即为每个连接 advertised window 的最大值。为了提高性能,必须增加套接字缓存区的大小。否则,这些值必须小于内部驱动器的资源,以便在内部驱动器的资源耗尽之前关闭 TCP 窗口。
接收缓存区大小取决于 TCP 窗口大小、TCP 最大段的大小和接收输入帧所需的时间。由于最大段的尺寸为 300 个字(一个 MODBUS 请求需要最大 256 字+MBAP 报文头),如果需要 3 帧进行缓存,可将套接字缓存区大小调整为 900 字。为了满足最大的缓存需求和预定的时间,可以增加 TCP 窗口的大小。
TCP-NODELAY:
通常,小报文(称为:tinygrams)在局域网(LAN)上的传输不会产生问题,因为多数局域网是不拥堵的,但是,这些 tinygrams 在广域网上将会造成拥堵。一个称为“NAGLE 算法”的简单方案是:收集小量的数据,当前面报文的 TCP 确认到达时再用单个进行发送。
为了获得更好的实时特性,建议:将小量的数据直接发送,而不要试图将其收集到一个段内再发送。这就是为什么建议强制 TCP-NODELAY 选项,这个选项禁用客户机和服务器连接的“NAGLE算法”。
SO-REUSEADDR:
当 MODBUS 服务器关闭一个由远端客户启动的 TCP 连接时,在这个连接处于“时间等待”状态(两个 MSL:最大段寿命)的过程中,该连接所用的本地口号不能被再次用来打开一个新的连接。
建议:为每个客户机和服务器连接,指明 SO-REUSEADDR 选项,以迂回这个限制。此选项允许为自身分配一个口号,它作为连接的一部分在 2MSL 期间内等待客户机并侦听套接字接口。
SO-KEEPALIVE:
TCP/IP 协议缺省状态下,不通过空闲的 TCP 连接发送数据。因此,如果在 TCP 连接端这个过程没有发送数据,在两个 TCP 模块间就没有交换任何数据。这就假设客户机端应用和服务器端应用均采用计数器来探测连接的存活性,以便关闭连接。
建议:在客户机与服务器连接两端均采用 KEEPALIVE 选项,以便查询另一端得知对方是否故障并死机,或故障并重新启动。
然而,我们必须牢记,采用 KEEPALIVE 可能引起一个非常良好的连接,在瞬间故障时通信中断,如果保持连接计时器计时周期太短,将占用不必要的网络带宽。
整个 TCP 层的参数
TCP 连接建立超时:
多数伯克利推出的系统将新连接建立的时限设定为 75 秒,这个缺省值应该适应于实时的应用限制。
保持连接参数:
连接的缺省空闲时间是 2 小时。超过此空闲时间将触发一个保持连接试探过程。第一个保持连接试探后,在最大次数内每隔 75 秒发送一个试探,直到收到对试探的应答为止。
在一个空闲连接上发出保持连接试探的最大数是 8 次。如果发出最大试探次数之后而没有收到应答,TCP 向应用发出一个错误信号,由应用来决定关闭连接。
超时与重发参数:
如果检测到一个 TCP 报文丢失,将重发此报文。检测丢失的方法之一是管理重发超时(RTO),如果没有收到来自远端的确认,超时终止。
TCP 进行 RTO 的动态评估。为此,在发送每个非重发的报文后测量往返时间(RTT)。往返时间(RTT)是指报文到达远端设备并从远端设备获得一个确认所用的时间。一个连接的往返时间是动态计算的,然而,如果 TCP 不能在 3 秒钟内获得 RTT 的估计,那么,就设定 RTT 的缺省值为 3 秒。
如果已经估算出 RTO,它将被用于下一个报文的发送。如果在估算的 RTO 终止之前没有收到下一个报文的确认,启用指数补偿算法。在一个特定的时间段内,允许相同报文最大次数的重发。之后,如果收不到确认,连接终止。
可以对某些栈设置连接终止之前重发的最大次数和重发的最长时间。
在 TCP 标准中定义了一些重发算法:
1) Jacobson RTO 估计算法用来估计重发超时(RTO);
2) Karn 算法指出,在重发段,不应进行 RTO 估计;
3) 指数补偿算法定义:对于 64 秒时间上限内每一次重发,加倍重发超时;
4) 快速重发算法允许在收到 3 个重复确认之后进行重发。考虑这个算法是因为:在 LAN 上,可能会导致报文丢失的检测快于等待 RTO 终止的检测。
在 MODBUS 实现中,推荐使用这些算法。
4.3.3 IP 层的参数配置
下列参数必须在 MODBUS 实现的 IP 层进行配置:
· 本地 IP 地址:IP 地址可以是 A、B 或 C 类的一种。
· 子网掩码:可基于各种原因,将 IP 网络划分成子网:使用不同的物理介质(例如:以太网、广域网等)、更有效的使用网络地址、以及控制网络流量的能力。子网掩码必须与本地 IP 地址的类型相一致。
· 缺省网关:缺省网关的 IP 地址必须与本地 IP 地址在同一子网内。禁止使用 0.0.0.0 的值。如果没有定义网关,那么此值可设为 127.0.0.1 或本地 IP 地址。
注:MODBUS 报文传输服务在 IP 层上不要求段功能。
应该利用本地 IP 地址、子网掩码和省缺网关(不同于 0.0.0.0)配置本地 IP 端。
4.4 通信应用层
4.4.1 MODBUS 客户端

4.4.1.1 MODBUS 客户端设计
MODBUS/TCP 协议使得能够对一个客户端进行简单的设计。下图描述了客户端发送MODBUS 请求并处理 MODBUS 应答的主要处理过程。

一个 MODBUS 客户机可以接收三类事件:
1) 一个来自用户应用的发送请求的新需求,在这种情况下,必须对 MODBUS 请求进行编码,并使用 TCP 管理组件服务通过网络进行发送 MODBUS 请求。下层(TCP 管理模块)会返回一个错误信息,这些错误信息是由于 TCP 连接错误或其他错误信息所导致的。
2) 来自 TCP 管理的一个响应,在这种情况下,客户端必须分析响应的内容,并向用户应用发送一个证实。
3) 由于无响应而超时结束。可以通过网络发送一个重试电文,或向用户应用发送一个否定证实。
注:这些重试是由 MODBUS 客户机启动的,可以在无 TCP 确认的情况下由 TCP 层来进行其它类型的重试。

下面给出了实例:从地址为 05 的远端服务器读 1 个字的 MODBUS 请求 ADU 编码 :

事务处理标识符
事务处理标识符用于将请求与未来响应之间建立联系。因此,对 TCP 连接来说,在同一时刻,这个标识符必须是唯一的。有几种使用此标识符的方式:
- 例如:可以作为一个带有计数器的简单“TCP 顺序号”,在每一个请求时增加计数器;
- 也可以用作智能索引或指针,来识别事务处理的内容,以便记忆当前的远端服务器和未处理的请求。
通常,在 MODBUS 串行链路上,客户机必须一次发送一个请求。这意味着这个客户机在发送第二个请求之前必须等待对第一个请求的回答。在 MODBUS TCP 上,可以向同一个服务器发送多个请求而不需等待服务器的证实。MODBUS/TCP 到 MODBUS 串行链路之间的网关负责保证这两种操作之间的兼容性。
服务器收接受的请求数量取决于其容量,即:服务器资源量和 TCP 窗口尺寸。同样,客户机同时启动事务处理的数量也取决于客户机的资 源容量。这个实现参数称为“NnmberMaxofClientTransaction”,必须作为 MODBUS 客户机的一个特性进行描述。根据设备的类型,此参数取值为 1~16。
单元标识符
在 MODBUS 或 MODBUS+串行链路子网中对设备进行寻址时,这个域是用于路由的目的。在这种情况下,“Unit Identifier”携带一个远端设备的 MODBUS 从站地址:
- 如果MODBUS服务器连接到MODBUS+或MODBUS串行链路子网,并通过一个桥或网关配置地址这个服务器,MODBUS单元标识符对识别连接到网桥或网关后的子网的从站设备是必需的。目的IP地址识别了网桥本身的地址,而网桥则使用MODBUS单元标识符将请求转交给正确的从站设备。
- 分配串行链路上MODBUS从站设备地址为1~247(10进制),地址0作为广播地址。
对 TCP/IP 来说,利用 IP 地址寻址 MODBUS 服务器;因此,MODBUS 单元标识符是无用的。必需使用值 0xFF。
- 当对直接连接到TCP/IP网络上的MODBUS服务器寻址时,建议不要在“单元标识符”域使用有效的MODBUS从站地址。在一个自动系统中重新分配IP地址的情况下,并且如果以前分配给MODBUS服务器的IP地址又被指配给网关,使用一个有效的从站地址可能会由于网关的路由不畅而引起麻烦。使用无效的从站地址,网关仅是简单地废弃MODBUD PDU,而不会有任何问题。建议:在采用0xFF作为“单元标识符”的无效值。
注:0 也可以用作与 MODBUS/TCP 设备直接通信。
4.4.1.3 处理 MODBUS 证实
在 TCP 连接中,当收到一个响应帧时,位于 MBAP 报文头中的事务处理标识符用来将响应与先前发往 TCP 连接的原始请求联系起来:
#如果事务处理标识符没有提及任何未解决的事务处理,那么必须废弃响应;
#如果事务处理标识符提及了未解决的事务处理,那么必须分解响应,以便向用户应用发送 MODBUS 证实(肯定的或否定的证实);
分解响应就是检验 MBAP 报文头和 MODBUS PDU 的响应:
· MBAP 报文头
在检验协议标识符必为 0x0000 以后,长度给出了 MODBUS 响应的大小。
如果响应来自直接连接到 TCP/IP 网络的 MODBUS 服务器设备,TCP 连接识别码足以清晰地识别出远端服务器。因此,MBAP 头中携带的单元标识符是无效的,必须废弃这个单元标识符。
如果将远端服务器连接在一个串行链路子网上,并且响应来自一个网桥、路由或网关,那么单元标识符(值≠0xFF)识别发送初始响应的远端 MODBUS 服务器。
· MODBUS 响应 PDU
必须检验功能码,根据 MODBUS 协议,分析 MODBUS 的响应格式:
#如果功能码与请求中所用的功能码相同,并且如果响应的格式是正确的,那么,向用户应用发出MODBUS响应作为肯定的证实。
#如果功能码是一个MODBUS异常码(功能码+80H),向用户应用发出一个异常响应作为肯定的证实。
#如果功能码与请求中所用的功能码不同(= 非预期的功能码),或如果响应的格式是错误的,那么,向用户应用发出一个错误信号作为否定的证实。
注:肯定证实是指服务器收到请求命令并做出响应的证实。并不意味着服务器能够成功地完成请求命令中要求的操作(MODBUS 异常响应指明执行操作失败)。

4.4.1.4 超时管理
对 MODBUS/TCP 上事务处理所需响应时间有意不作规定。
这是因为:从毫秒级的 I/O 扫描到延时几秒钟的远距离无线链路,预期 MODBUS/TCP 会用于可能最宽泛的通信场合。
从客户机的角度,超时必须考虑网络上预期的传输延迟,以便确定一个合理的响应时间。这种传输延迟可能是交换式以太网中的几个毫秒,或广域网连接中的几百毫秒。
反过来讲,任何客户机启动应用重试使用的超时时间应该大于预期的最大的合理响应时间。如果不遵循这一点,目标设备或网络就存在过度拥挤的潜在危险,而反过来会导致更多的错误。这是一个应该始终避免的特性。
因此,在实际中,在高性能应用中所使用的客户机超时似乎总是与网络拓扑和期望的客户机性能有关。
时间因素不很重要的系统经常采用 TCP 缺省值作为超时值,在多数平台上,几秒钟之后将报告通信故障。
4.4.2 MODBUS 服务器端

MODBUS 服务器的作用是为应用对象提供访问以及为远端客户机提供服务。
根据用户应用,提供不同类型的访问:
§ 简单访问:获得或设定应用对象的属性;
§ 高级访问:启动一个特定的应用服务
MODBUS 服务器必须:
§ 将一个应用对象映射成可读或可写的MODBUS对象,以便获得或设定应用对象的属性;
§ 提供一种对应用对象启动服务的方法;
在运行过程中,MODBUS 服务器必须分析接收到的 MODBUS 请求,处理所需的操作,返回 MODBUS 响应。
4.4.2.1 MODBUS 服务器设计
MODBUS 服务器设计取决于如下两个方面:
§ 对应用对象访问的类型(对属性的简单访问或对服务的高级访问);
§ MODBUS服务器与用户应用之间交互作用的类型(同步或异步)。
下图描述了服务器进行的主要处理过程,以便获得来自 TCP 管理的 MODBUS 请求,然后,分析请求,处理所需的操作,返回 MODBUS 响应。

前面的操作示意图示出的那样:
§ MODBUS服务器本身可以立即处理一些服务,没有与用户应用之间的交互作用;
§ 一些服务还可能需要与被处理的用户应用进行明显的交互作用;
§ 有些高级服务需要调用特定的接口,即:MODBUS后台服务。例如:可能根据用户应用层协议,使用若干个MODBUS请求/响应事务处理的时序来启动用户应用服务。后台服务负责所有单个MODBUS事务处理的正确进行,以便于执行全局用户应用服务。
MODBUS 服务器可以接收并同时为多个 MODBUS 请求提供服务。服务器可以同时接收MODBUS 请求的最大数量是 MODBUS 服务器的主要特性之一。这个数量取决于服务器的设计以及它的处理和存储能力。将这个实现参数称为“NumberMaxOfServerTransaction”,必须作为 MODBUS 服务器的一个特性描述这个实现参数。根据设备的能力,它的取值范围为:1~16,。
“NumberMaxOfServerTransaction”参数对 MODBUS 服务器的操作和性能有非常显著的影响。尤其重要的是,所管理的并发 MODBUS 事务处理的数量可能影响服务器对 MODBUS 请求的响应时间。
4.4.2.2 MODBUS PDU 检验
下图描述了 MODBUS PDU 检验操作。

MODBUS PDU 检验功能首先是分解 MBAP 报文头。必须检验协议标识符域:
§ 如果与 MODBUS 协议类型不同,那么废除这个指示。
§ 如果是正确的(= MODBUS 协议类型;值为 0x00),立即举例说明一个 MODBUS 事务处理。
一个服务器可以距离说明的 MODBUS 事务处理的最大数量由参数“NumberMaxOfTransaction”(系统或配置参数)来定义。
在无效的事务处理的情况下,服务器生成一个 MODBUS 异常响应(异常码 6:服务器繁忙)。
如果事务处理是有效的,它将被启动,以便存储下列信息:
§ 用于发送指示的TCP连接标识符(由TCP管理给出)
§ MODBUS事务处理ID(MBAP报文头中给出)
§ 单元标识符(MBAP报文头中给出)
然后,分解 MODBUS PDU。首先分析功能码:
§ 当无效时,生成MODBUS异常响应(异常码1:无效功能)
§ 如果接收功能码,服务器启动一个“MODBUS服务处理”操作。
4.4.2.3 MODBUS 服务处理

根据后面实例中的设备软件和硬件结构,可以用不同的方式进行要求的 MODBUS 服务处理:
· 在一个小型设备或单线程体系结构内,MODBUS服务器可以直接访问用户应用数据,服务器自身可以本地处理要求的服务,而无需调用后台服务。
根据“MODBUS 协议规范”,进行这种处理。在出现错误的情况下,生成 MODBUS 异常响应。
· 在一个模块化的多处理器的设备或多线程体系结构中,“通信层”和“用户应用层”是两个独立的实体,通信实体可以完全地处理一些不重要的服务,而其他的服务需要应用后台服务与用户应用实体协调完成。
为了实现与用户应用的交互作用,MODBUS 后台服务必须执行所有适当的机制,以便处理用户应用的事务处理,并且正确管理用户应用调用和相应的响应。
4.4.2.4 用户应用接口(后台接口)
在 MODBUS 后台服务中,可以执行几种策略来完成工作,虽然从用户网络吞吐量、接口带宽使用、响应时间、甚至设计工作量的角度,这几种策略是不均衡的。
MODBUS 后台服务将对用户应用采用适当接口:
· 或基于串行链路的物理接口,或双口RAM方案,或一条简单的I/O电缆,或由操作系统提供的基于报文传输服务的逻辑接口。
· 到用户应用的接口可以是同步的或异步的。
MODBUS 后台服务还将使用适当的设计模式来得到/设定目标属性或触发服务。在某些情况下,一个简单的“网关模式”将是足够的。在其他情况下,从简单的交换表历史到更复杂的重复机制中,设计者将必须执行带有高速缓存策略的“代理服务器模式”。
MODBUS 后台服务有责任实现协议的转换,以便与用户应用进行交互作用。因此,它必须具有机制来实现报文的分拆和重组、数据一致性保证以及所有需要的同步等功能。
4.4.2.5 MODBUS 响应的生成
一旦处理请求,MODBUS 服务器必须使用适当的 MODBUS 服务器事务处理生成一个响应,并且必须将响应发送到 TCP 管理组件。
根据处理结果,可以生成两类响应:
肯定的MODBUS响应:
§ 响应功能码 = 请求功能码
MODBUS异常响应:
§ 目的是为客户机提供与处理过程检测到的错误相关的信息
§ 响应功能码 = 请求功能码+0x80
§ 提供异常码来表明出错的原因。

MODBUS 响应 PDU 必须以 MBAP 报文头做前缀,使用事务处理正文中的数据生成 MBAP 报文头。
· 单元标识符
当在所收到的 MODBUS 请求中给出单元标识符时,拷贝这个单元标识符,并将其存储在事务处理的正文中。
· 长度
服务器计算 MODBUS PDU 和单元标识符字的大小。在“长度”域中设置这个值。
· 协议标识符
设置协议标识符域为 0x0000(MODBUS 协议),在所收到的 MODBUS 请求中给出协议标识符。
· 事务处理标识符
设置这个域为“事务处理标识符”值,它与初始请求有关,并将其存储在。
利用事务处理正文中存储的 TCP 连接对正确的 MODBUS 客户机返回 MODBUS 响应。当发送响应时,事务处理正文必须释空闲的。
5 实现指南
本章的目的是提出一个实现报文传输服务的实例。下面所描述的模型可用作客户机或服务器实现 MODBUS 报文传输服务过程的指南。
5.1 对象模型示意图

四种主要程序包构成对象模型示意图:
1) 配置层,它配置和管理其它程序包组件的操作模式
2) TCP 管理,它使 TCP/IP 栈和管理 TCP 连接的通信应用层连接。这指的是套接字接口的管理。
3) 通信应用层,它由在一侧的 MODBUS 客户机和在另一侧的 MODBUS 服务器组成。该程序包和用户应用链接。
4) 用户应用,它和设备应用相对应,它完全与设备有关,因此在本文件中不予讨论。
本模型与实现的选择无关,例如:OS 类型、存储管理等。为保证这种无相关性,在 TCP 管理层和通信层之间以及在通信层和用户应用层之间使用普通界面层(generic Interface layers)。
有不同的实现方法实现该界面:两项任务之间的传输、共享存储器、串行链接界面、过程呼叫等。
为定义下面的实现模型,作了一些假定:
#静态存储器管理;
#服务器的同步处理;
#处理有关所有套接字接收的任务。
5.1.1 TCP 管理程序包

TCP 管理程序包包括下列类:
ClnterfaceConnexion:该类的作用是管理用于连接的存储库。
CltemConnexion:该类含有描述连接所需要的所有信息。
CTCPConnexion:该类提供自动管理 TCP 连接的方法(CStackTCP_IP 提供接口套接字)。
CconnexionMngt:该类管理所有连接,并通过 CinterfaceindicationMsg 和CinterfaceRoseponseMsg向 MODBUS 服务器/MODBUS 客户机发送请求/响应。该类还处理连接建立的访问控制。
CMBAP:该类提供读/写/分析 MODBUS MBAP 的方法。
CStackTCP_IP:该类执行套接字服务并提供栈的参数配置。
5.1.2 配置层程序包

配置层程序包包括下列类:
TConfigreObject:该类将各组件相互配置所需的数据分组。用 CoperatingMode 类中的 m_Confire方法填充这个结构。每个需要配置的类从这个对象中取得自己的数据。配置数据与实现本身有关。因此,提供该类的属性表作为一个实例。
CoperatingMode:该类的作用是填充 TConfigueObject(根据用户的配置)和管理下述类的操作模式。
#CMODBUSServer
#CMODBUSClient
#CconnexionMngt
5.1.3 通信层程序包

通信应用层程序包包括以下各类:
CMODBUSServer : 从 CinterfaceIndicationMsg 中 接 收 MODBUS 询 问 ( 通 过 m_ServerRecievingMessage 方法)。该类的作用是根据询问建立 MODBUS 响应或 MODBUS 异常(从网络进入)。该类实现 MODBUS 服务器的 Graph State。只有类 CoperatingMode 发送了用户配置和正确的操作模式,才可能生成响应。
CMODBUSClient:从类 CinterfaceUserApplication 中读取 MODBUS 询问,客户机的任务是用 m_ClientReceivingMessage 方法接收询问。该类实现 MODBUS 客户机的 State Graph,并且管理链接
带有响应的询问的事务处理(来自网络的)。只有类 CoperatingMode 发送了用户配置和正确的操作模式,才能通过网络发送询问。
CTransaction:该类实现管理事务的方法和结构。
5.1.4 接口类
CInterfaceUserApplication:该类表示与用户应用的接口,它提供两种访问用户数据的方法。在实际的实现中,根据硬件和软件设备的能力,用不同的方式实现这种方法(相当于一个终端驱动器、访问 PCMCIA 的实例、共享存储器等)。
CInterfaceIndicationMsg:该接口类用来从网络向 MODBUS 服务器发送询问,以及从网络向客户机发送响应。该类使 TCPManagement 和通信应用层程序包连接(从网络中)。该类的实现与网络有关。
CInterfaceResponseMsg:该接口类用于从服务器接受响应,以及从客户机向网络发送询问。该类使通信应用层程序包和 TCPManagement 连接(向网络)。该类的实现和设备有关。
5.2 类和方法的描述
5.2.1 MODBUS 服务器端的类


5.2.2 MODBUS 客户机类


5.2.3 接口的类
5.2.3.1 接口指示类
类名:CInterfaceIndicationMsg
直接已知的子类
CConnexionMngt
类名:CInterfaceIndicationMsg
从 TCP_Management 向 MODBUS 服务器或客户机发送报文的类
Stereotype 接口

5.2.3.2 接口响应类
类名:CInterfaceResponseMsg
直接已知的子类:
CMODBUSClient、CMODBUSServer
class CInterfaceResponseMsg
从客户机或服务器向 TCP_Management 发送响应或询问的类
Stereotype 接口

5.2.4 连接管理类
类名:CConnexionMngt
类名:CConnexionMngt
管理所有 TCP 连接的类
Stereotype 实现类

