通信基础 - ADS通信
一、基本概念
ADS (Automation Device Specification)是 TwinCAT 原生通信协议,它通过基于 AmsNetId(6 字节逻辑设备地址)和 AmsPort(2字节逻辑端点)构建的统一寻址方案,将软件组件(PLC 运行时、HMI 应用程序、自定义服务器)连接起来。
-
AmsNetId(AMS 逻辑设备地址):标识 ADS 网络中的一个逻辑设备,不是一台物理机器,而是一个参与 ADS 通信的独立身份。
-
AmsPort(AMS 逻辑端点):标识一个逻辑设备上提供的一个逻辑服务。
ADS协议包含角色:ADS路由器,ADS客户端,ADS服务器。
| 角色 | 概念 | AMS 身份,AMS(Automation Message Specification 自动化消息规范) |
|---|---|---|
| ADS 路由器 | 逻辑设备 | 拥有 AmsNetId |
| ADS Server | 逻辑端点 | 借用路由器的 AmsNetId,拥有自己固定的 AmsPort |
| ADS Client | / | 借用路由器的 AmsNetId,临时随机分配 AmsPort,因为响应帧要能送回来 |
把 ADS 网络想象成一栋办公楼:
- 路由器 = 大楼,有楼号(AmsNetId),比如"中银大厦"
- Server = 房间,有房间号(AmsPort),比如"801 室"、"851 室",来访者可以按房间号找到它
- Client = 来访者,进门时前台给他一个临时访客牌号(临时 AmsPort),等别人回访时按这个牌号找他。他不是楼里的固定租户,办完事就走了
二、ADS路由器
2.1 基础
路由器就是一个进程,开启了两个 TCP 监听器(也可能会开启TCPClient),分别对接两类对象。
| 对象 | 在哪 | 举例 |
|---|---|---|
| 本地的 ADS Client / Server | 同一台机器,同一个进程 | 本机上的 PLC Runtime、你写的 AdsClient |
| 远端的 ADS 路由器 | 另一台机器(或另一个容器) | IP 为 192.168.0.2 的远端路由器 |
这两类对象性质完全不同,所以路由器分别开设了和他们的通道。
2.2 环回通道(Loopback Channel)
| 配置项 | 默认值 | 含义 |
|---|---|---|
| LoopbackIP | 127.0.0.1 | 绑定到哪个 IP |
| LoopbackPort | 48898 | 绑定到哪个端口 |
-
通信对象:环回通道的通信对象是本机的 ADS Client 和 ADS Server,当你写一个 AdsClient 然后 client.Connect() 的时候,底层就是连到环回通道。
-
啥是环回:127.0.0.1 就是本机环回地址。本机的 Client/Server 连 127.0.0.1:48898,数据根本不经过网卡,在操作系统内核里就转回来了。
2.3 外部通道(External Channel)
| 配置项 | 默认值 | 含义 |
|---|---|---|
| TcpIP | 0.0.0.0 | 绑定本机所有网卡,不可配置 |
| TcpPort | 48898 | 绑定到哪个端口 |
- 通信对象:远端的 ADS 路由器。
- 啥是外部:这是给外部网络中的远端路由器连进来的通道。远端路由器通过 IP 网络(比如 192.168.0.2:48898)连接,跨机器 / 跨网段。
2.4 更多
2.4.1 通道的IP地址
你可能发现两个通道共用端口 48898,但绑在不同 IP 上,所以不会造成冲突。操作系统区分 TCP 连接靠的是四元组(源IP、源端口、目标IP、目标端口),127.0.0.1:48898 和 0.0.0.0:48898 是两个不同的监听器。
2.4.2 开发者关注哪一个通道
| 你的角色 | 你关注的通道 | 你要配的地址 |
|---|---|---|
| 写本地 ADSClient/ADSServer 的人 | 环回通道 | 默认 127.0.0.1:48898,通常不用管 |
| 配置跨机器通信的人 | 外部通道 | 在路由表里添加远端路由器的 IP |
| 跑独立路由器的人 | 两个通道都要配 | 确保端口不跟 TwinCAT 冲突 |
2.4.3 ADS路由器从哪里来
很多人从来没有创建过ADS路由器,但是一直在使用ADS通信,那这个路由器是从哪来的?
在安装 TwinCAT XAE/XAR 的时候,安装程序在你的 Windows 上注册了一个系统服务,叫 TwinCAT System Service(服务名 TcSysSrv)。这个服务里就内置了 ADS 路由器。它做了这些事:
- 开机自启——作为 Windows Service 随系统启动,你不需要手动运行
- 自动监听 127.0.0.1:48898——这就是之前说的"环回通道"
- 自动监听 0.0.0.0:48898——外部通道,给远端路由器连入
- 自动生成本机 AmsNetId——通常从本机 IP 派生,如 192.168.1.10.1.1
- 自动加载路由表——从 C:\TwinCAT\3.1\Target\StaticRoutes.xml 读取
所以当你写如下代码连接PLC的时候:
var client = new AdsClient();
client.Connect(new AmsAddress(targetNetId, 851));
底层的完整链路是
AdsClient
│
│ TCP 连接到 127.0.0.1:48898(TwinCAT 系统服务)
▼
TwinCAT System Service(系统服务内置 ADS 路由器,你从没创建过但它一直在)
│
│ 查路由表,TCP 转发到远端路由器
▼
远端 TwinCAT 机器上的 ADS 路由器
│
│ 本地投递
▼
远端 PLC Runtime (AmsPort 851)
三、ADSClient
Client 的工作方式是,通过 TCP 连接到本地路由器的环回端口(127.0.0.1:48898),然后在这个 TCP 连接上发送/接收 AMS 帧。
| 属性 | 默认值 | 说明 |
|---|---|---|
| Client IP 地址 | 无 | Client 主动连路由器,操作系统分配临时源 IP |
| Client TCP 端口 | 无 | 操作系统分配临时源端口(ephemeral port) |
| Client AmsNetId | 继承本地路由器的 AmsNetId | Client 不独立拥有 AmsNetId,它属于本地路由器 |
| Client AmsPort | 由本地路由器动态分配 | 路由器给每个连入的 Client 分配一个临时 AmsPort |
Client 是路由器的"租客"。 它搬进路由器这座楼,路由器给它分配一个房间号(临时 AmsPort),外界看到的发件地址是"路由器的 AmsNetId + 分配的临时 AmsPort"。Client 不需要自己有 IP 地址或 TCP 端口——它直接用路由器的。
四,ADSServer
ADSServer 工作方式和 Client 类似,也是通过 TCP 连接到本地路由器的环回端口,也没有自己的 IP 地址和 TCP 端口。
唯一区别在于,Server 有一个固定的 AmsPort,这是你创建 Server 时指定的。举几个典型的例子。
-
Ring 0 NC :就是PLC的NC,端口501
-
TC3 PLC 运行时系统 1 :就是PLC的第一个运行时,端口851
-
TCP/IP 服务器 :就是TF6310,端口10201
| 属性 | 值 | 谁定的 | 说明 |
|---|---|---|---|
| Server IP 地址 | 无 | — | Server 主动连路由器,操作系统分配临时源 IP |
| Server TCP 端口 | 无 | — | 操作系统分配临时源端口(ephemeral port) |
| Server AmsNetId | 继承本地路由器的 AmsNetId | 路由器决定 | Server 不独立拥有 AmsNetId,它属于本地路由器 |
| Server AmsPort | 如501、851、26000 | 开发者定的 | 这是 Server 的身份标识,必须在合法范围内 |
五,路由表
路由表就是 AmsNetId → IP地址 的映射表。路由器收到一个 AMS 帧,看目标 AmsNetId,查表找到对方路由器的 IP 地址,然后通过 TCP 转发过去。
下图是我笔记本的路由表,硬件有一个CX系列的PLC。PLC的ADS路由器的AmsNetId是192.168.1.110.1.1,PLC网卡的IP地址是192.168.1.110。

用我笔记本和PLC的ADS路由器的通信说明转发过程,我笔记本网卡的IP地址是192.168.1.95,笔记本上ADS路由器的AmsNetId是192.168.1.95.1.1。
转发过程分三步:
-
第一步:本机 Client → 本机 Router(环回通道)
Client 发出 AMS 帧,帧的头部如下
Source: [192.168.1.95.1.1 : Client临时AmsPort] Target: [192.168.1.110.1.1 : 851] Payload: ADS Read/Write/ReadWrite这个AMS 帧通过 TCP 连接(127.0.0.1:48898)先发给本机路由器。
-
第二步:本机 Router → PLC Router(外部通道)
本机路由器收到帧后:- 读取 Target AmsNetId = 192.168.1.110.1.1
- 查路由表:192.168.1.110.1.1 → 192.168.1.110
- 通过 TCP 连接到PLC路由器 192.168.1.110:48898,原封不动转发整个 AMS 帧
-
第三步:PLC Router → PLC运行时 Server(环回通道)
PLC路由器收到帧后:
- 读取 Target AmsPort = 851
- 查本地注册表,AmsPort 851 对应到 PLC 的第一个运行时
- 通过PLC内部换回通道,将帧投递给 PLC 运行时
有2个要注意的地方:
- 如果是笔记本在本地模拟运行PLC代码,那么 Target AmsNetId 就是本机路由器的 AmsNetId,第一步 Client 发出 AMS 帧后,本机路由器发现是给自己的,就不用查路由表了,直接眺到第三步按 AmsPort 本地投递。
- 路由必须两端都配置。A 配了到 B 的路由,B 也必须配到 A 的路由,否则 B 的回程帧无法送达。
六,ADS通信中的TCP角色
从TCP的角度看ADS的三个角色。
| ADS 角色 | TCP 角色 | 行为 |
|---|---|---|
| ADS Client | TCP Client | 主动连到ADS路由器 |
| ADS Server | TCP Client | 主动连到ADS路由器 |
| ADS Router | TCP Server/TCP Client | 既监听,等人连进来。也主动连远端 Router |
七,AMS 消息和 TCP 消息的关系
AMS消息和TCP消息的关系类似于信件和邮递车。
其实ADS的AMSNetId,AmsPort和TCP的IP,Port毫无关系,用IP加上.1.1的后缀当AMSNetId只是一种方便的习惯而已。
- AMS 帧是一个独立定义的协议数据单元
- AMS 帧本身不包含任何 TCP/IP 信息,它不知道 IP 地址、不知道 TCP 端口

浙公网安备 33010602011771号