☰
VM虚拟机中欧姆龙PLC的Fins通讯:从桥接配置到故障排查
2026/10/3 5:14:57 网站建设 项目流程

搞工控上位机或机器视觉的朋友,大概都遇到过这个组合:宿主机上跑一个VMware虚拟机,虚拟机里装着Win10和视觉软件,工控机通过交换机连着一台欧姆龙PLC,两者之间要靠Fins协议把数据打通。这套东西听起来没什么技术含量,真做起来却到处是坑——VM的网络模式选错导致PLC根本ping不到虚拟机、Fins节点号对不上一直报“目标节点不存在”、9600端口被Windows防火墙拦掉、抓包抓了一堆也不知道怎么看。这篇文章就把VM环境下欧姆龙PLC走Fins TCP/UDP通讯的完整流程、协议细节和排障经验一次讲透,从原理到实操到避坑,都按我实际跑过的项目来写。

我会尽量照顾两种读者:一种是刚接触Fins通讯、对协议帧还不熟悉的新手,可以照着后面的配置步骤和报文样例一步步来;另一种是被VM网络模式和通讯故障折磨过、想找系统排查方法的工程师,可以直接跳到第5、6章对照检查。整篇内容围绕“VM”、“欧姆龙PLC”、“Fins”、“TCP/UDP”这几个关键词展开,不整虚的,全部是我踩过的坑和验证过的方法。

1. 场景与方案:为什么非要在VM里跑上位机,又该怎么选网络

1.1 实际工作场景

先说清楚“VM与欧姆龙PLC通讯”这个需求是怎么来的。我接触到的绝大多数情况是这样的:公司买了海康VM(VisionMaster)这类机器视觉软件,或者在第二台上位机里部署一套组态软件,为了不污染宿主机环境,也为了多台电脑之间快速复制开发环境,工程师习惯把所有工具装进VMware虚拟机,装的是Win10。到了现场,虚拟机里的视觉软件需要和欧姆龙PLC交换数据——视觉检测结果要写到PLC的DM区,或者PLC的信号要触发视觉拍照。VM作为一个跑在物理机上的“客户机”,这时候必须和局域网里的真实PLC完成双向通讯。

这个场景在设备集成项目中非常普遍,但很多人在VM里配网络时翻车。常见的现象是:PLC能ping通宿主机,却ping不通虚拟机;上位机软件一直在连PLC,但PLC侧根本收不到连接请求;或者通讯一开始正常,过几分钟就掉线重连。这些问题百分之七八十都不是Fins协议本身的问题,而是VM的网络模式没选对。

所以第一步不是学Fins帧格式,而是把VM的网络地基打好。

1.2 VM三种网络模式怎么选

VMware虚拟机提供了三种常用网络模式:桥接模式(Bridged)、NAT模式、仅主机模式(Host-only)。它们对Fins通讯的意义完全不一样。

网络模式虚拟机与局域网的关系能否被PLC主动访问适合场景
桥接(Bridged)虚拟机相当于一台独立电脑,IP与宿主机在同一局域网能Fins/Modbus TCP等工控通讯首选
NAT虚拟机通过宿主机共享IP上网,外部看只有宿主机一个IP默认不能,需端口映射虚拟机上网、装软件,不适合PLC通讯
仅主机(Host-only)虚拟机只能和宿主机通信,外部设备不可见不能本地调试、隔离环境,不适合现场通讯

这里面的逻辑很直接:Fins TCP/UDP通讯需要上位机和PLC之间双向收发数据包。如果VM用NAT模式,PLC发送给虚拟机的数据包必须经过宿主机的NAT转换和端口映射,Fins UDP这种无连接的协议在NAT下极其容易丢包;而Fins TCP虽然可以主动连接出去,但如果PLC作为服务端监听,外部请求进到虚拟机也需要额外的端口转发配置。现场没那么多时间做映射,所以我的结论一直很明确:做PLC通讯,VM必须用桥接模式。

有个细节要单独提醒:有些电脑同时插了有线网卡和无线网卡。VMware桥接网络默认会“自动选择”一个有网卡的接口,不一定是你连PLC的那块。我遇到过好几次,PLC在同一台交换机的有线网段,但虚拟机拿着无线网卡去桥接,结果怎么ping都不通。所以VM里要手动指定桥接到哪块物理网卡。

1.3 桥接模式的具体配置

配置路径在VMware里是:编辑虚拟机设置 -> 网络适配器 -> 网络连接 -> 选“桥接模式”,然后在“配置适配器”里勾选实际连接PLC的物理网卡(比如Realtek有线网卡),不要勾选“自动”或者把无线网卡也勾上。

虚拟机里的Win10再手工设一个固定IP,和PLC在同一个网段。举例:PLC内部以太网模块默认IP往往是192.168.250.1,子网掩码255.255.255.0,那虚拟机就设192.168.250.50,子网掩码255.255.255.0,网关不设也没关系。设完之后先做一件事:在虚拟机里ping一下PLC的IP,确认二层三层的连通性。ping不通的话,后面所有Fins配置都是白搭,这点别跳过。

2. Fins协议核心参数拆解:读懂节点号、单元号与帧格式

2.1 Fins是什么,怎么理解9600端口

Fins是欧姆龙PLC的工厂接口网络服务协议,全称是Factory Interface Network Service。它和国内工程师更熟悉的Modbus TCP不是一回事:Modbus是通用标准协议,各家PLC基本都支持;Fins是欧姆龙专有协议,特点是直接按PLC内部存储区地址来访问,不搞寄存器映射那一套。

从传输层看,Fins可以跑在TCP上,也可以跑在UDP上,默认端口都是9600。Fins/TCP适合需要长连接、大批量交换数据的场合;Fins/UDP则更轻量,一条命令一个响应,常用于高速点位控制。后面第4章会专门对比选型,这里先建立这个基本概念:9600是Fins服务的默认监听端口,不是随便填的。

如果PLC端口被改过,可以在PLC的以太网设置里查看和修改。端口改完之后,上位机这边也要跟着改,否则抓包时发现根本没有数据包到达PLC,因为目标端口是错的。

2.2 Fins帧里每个字节的用途(SA1/DA1等详解)

Fins帧的核心是10字节的FINS报文头部,后面跟着2字节命令码和若干数据。很多人被这一堆十六进制吓住,其实把它拆开看就很清楚。下面是一帧Fins UDP读DM区命令的完整报文:

80 00 02 00 00 01 00 00 00 00 01 01 82 00 64 00 01 00 01

这18个字节里,前10字节就是FINS头部:

字节名称本例值含义
1ICF0x80信息控制域,bit7=1表示需要响应
2RSV0x00保留字节,固定为0
3GCT0x02网关计数,固定为2
4DNA0x00目标网络号,0表示本地网络
5DA10x01目标节点号,即PLC的节点号
6DA20x00目标单元号,一般填0
7SNA0x00源网络号,0表示本地网络
8SA10x00源节点号,即上位机的节点号
9SA20x00源单元号,一般填0
10SID0x00服务标识符,用于请求和响应配对

10字节之后是命令码和数据。上例中01 01是内存区读命令,82表示DM区,00 64是起始地址D100,00 01是读取长度1个字。

这里最关键的几个参数是SA1和DA1。DA1是目标节点号,也就是你要访问的PLC节点。SA1是源节点号,也就是上位机自己的节点。很多第一次抓Fins包的人会问“SA1是什么意思”,其实就是发送方在Fins网络里的编号。欧姆龙PLC在Fins通讯中有严格的节点号校验,DA1填错,PLC会直接丢弃命令或者回一个“目标节点不存在”的错误,这也是Fins通讯最典型的坑,后面排查章节还会提到。

2.3 一条Fins/TCP完整链路:三次握手、Fins节点握手、读写指令

Fins/TCP和Fins/UDP在通讯过程上有本质区别。Fins/UDP是发一个命令帧,等一个响应帧,无连接;Fins/TCP则是先建立TCP连接,再做一次Fins层面的节点握手,然后才进入正常的读写指令交换。

用Wireshark抓一次Fins/TCP通讯,会看到这些包:

  1. TCP三次握手:SYN、SYN+ACK、ACK,建立9600端口的TCP连接。
  2. Fins节点地址握手:客户端发送一个命令码为0000的FINS/TCP连接帧,里面带有上位机节点号;PLC收到后返回同样的命令,并确认节点号。这个过程就是Fins/TCP特有的“节点分配/确认”,相当于告诉PLC“我是谁”。
  3. 正常的Fins读写指令,比如内存区读0101、内存区写0102。

我经常遇到有人拿TCP调试助手直接往PLC的9600端口发一帧Fins UDP报文,然后抱怨没响应。这就是没搞懂两者的区别:Fins/TCP必须先做节点握手,直接在TCP流里发裸FINS帧是不被接受的。反过来,Fins/UDP就不用握手,把报文发过去,PLC收到就回应。

举个例子,Fins/TCP内存区读命令的完整帧(含FINS/TCP头)长这样:

46 49 4E 53 00 1A 00 00 00 00 80 00 02 00 00 01 00 00 00 00 00 01 01 82 00 64 00 01 00 01

46 49 4E 53是ASCII码“FINS”,00 1A是携带数据的长度,00 00是命令,00 00 00 00是错误码,后面接的才是和UDP模式一致的FINS报文。注意:Fins/TCP报文里多了一层长度和命令字段,千万不要把UDP版本的报文明直接套到TCP连接里发。

2.4 Fins与Modbus TCP怎么选

既然热搜词里频繁出现“modbus tcp”,这里值得多说一句。现实中很多第三方设备或上位机软件并不原生支持Fins,反而更熟悉Modbus TCP。比如某些视觉软件、触摸屏、网关设备,它们内置的驱动列表里可能只有Modbus TCP,没有“欧姆龙Fins”这个选项。

从使用效果看,两者各有取舍:

对比项Fins TCP/UDPModbus TCP
协议归属欧姆龙专有通用开放标准
地址访问直接读DM/CIO/WR区,地址直观按功能码映射,需要查对照表
单条命令效率可跨区组合读写每次只能操作一种地址类型
调试工具需要会看FINS帧,门槛稍高调试助手、上位机库多,上手容易
跨品牌设备只适合欧姆龙PLC各类PLC、仪表、网关通吃

我的建议是:如果上位机是自己写代码或者用海康VM二次开发脚本,优先用Fins,因为地址直读直写,不用做寄存器偏移换算;如果对接的是第三方触摸屏、上位机组态软件或者网关,那就看对方支持什么。有些项目里,PLC作为Modbus TCP从站,把视觉结果映射到固定保持寄存器,方案也很成熟。这事没有绝对的优劣,只有哪个在当前工程链路里最省事。

3. VM与欧姆龙PLC通讯搭建全流程:从IP到软件参数

3.1 网络与端口调试

在把Fins协议搬出来之前,我建议先做一遍彻底的网络体检。顺序是:ping通、端口通、协议通。

第1步,在VM虚拟机里ping PLC的IP。如果ping不通,检查VM桥接模式和网卡绑定。第2步,测9600端口是否通。Windows上可以用PowerShell命令:

Test-NetConnection 192.168.250.1 -Port 9600

返回TcpTestSucceeded : True说明端口能访问。如果是Linux的VM或调试机,可以用nc:

nc -vz 192.168.250.1 9600

第3步才是用Fins命令验证协议。如果端口都不通,Fins报文发过去等于石沉大海。

这里要额外提一个端口冲突问题。有些人会把VMware的“VMnet8 NAT”或“VMnet1 Host-only”虚拟网卡和实际的Fins端口搅在一起,或者宿主机上装了其他工控软件占用了9600端口。遇到bind: address already in use这类报错,可以用netstat排查:

netstat -ano | findstr 9600

看看是谁占用了9600端口,是VMware的虚拟服务还是其他软件。如果被占用,把占用进程结束,或者换一个自定义端口并在PLC里同步修改。

3.2 PLC端的IP与节点号配置

PLC端配置是另一个重灾区。以常用的欧姆龙CP1H/CJ2M内置以太网口为例,IP一般在CX-Programmer的“设置”里修改,默认地址可能是192.168.250.1,节点号默认是1。用CX-Programmer在线连接到PLC后,打开PLC设置中的“内置Ethernet”选项卡,设置固定IP、子网掩码、端口号,同时确认Fins节点号。

节点号可以手动改成任意1到254之间的数,只要在整个Fins网络里不冲突就行。但有一个容易忽略的点:有些早期版本的CX-Programmer里,IP地址修改后,必须对PLC断电重启或者对以太网单元执行“重启”,新的IP和节点号才会真正生效。如果只在线下载设置不重启,你会看到PLC表面“理论上是新IP”,实际上网络层还是旧参数,白白浪费半小时。

另外,如果使用Sysmac Studio配置NJ/NX系列PLC,入口和参数名字会略有不同,但核心逻辑一致:把PLC的IP固定,Fins服务打开,端口9600,节点号规划清晰。节点号这一点我在项目里吃过亏,和PLC供应商的工程师对参数,对方问“节点号设的几”,我这边连PLC默认节点号都没确认过,导致一次通讯都发不出去。所以先花一分钟确认节点号,比反复猜报错信息有价值得多。

3.3 上位机Fins参数设计(以海康VM视觉软件为例)

上位机侧要填的参数一般包括:PLC的IP、端口9600、本地节点号、目标节点号、目标单元号。以海康VM软件为例,它本身没有内置“欧姆龙Fins”的傻瓜式驱动,工程上一般通过“脚本”或“二次开发”的方式,用C#或VB写一个Fins通讯类,把检测结果写到PLC指定地址。

我推荐的做法是:在VM的脚本里创建一个TcpClient,连接PLC的9600端口,先按Fins/TCP握手流程发送节点确认帧,再组装Fins内存写命令,把视觉OK/NG结果写到PLC的DM区或CIO区。核心代码逻辑不复杂,难点在于帧格式要拼对。

这里给出一个用C#构造Fins/TCP内存区写请求的思路,便于理解参数映射:

// 伪代码示意:构造FINS/TCP报文 byte[] finsHeader = { 0x80, 0x00, 0x02, // ICF + RSV + GCT 0x00, // DNA 本地网络 plcNode, // DA1 目标节点号 0x00, // DA2 单元号 0x00, // SNA 本地网络 localNode, // SA1 源节点号 0x00, // SA2 源单元号 sid++ // SID 服务标识 }; // 内存区写命令 0x0102 + 内存区码0x82 + 起始地址 + 长度 + 数据

在拼帧之前,先确认上位机这边的“本地节点号”是否和PLC侧配置一致。Fins的节点号不是随便填一个就能用,PLC在响应之前会校验DA1是否指向自己,同时也会记录SA1,后续响应帧要把DA1设置成这个SA1的值。如果上位机节点号和网络里其他设备冲突,比如有两台电脑都设成了节点1,PLC收到两个“节点1”的请求,响应到底发给谁就成了玄学。

这里的工程建议是:做一张参数表,把PLC节点号、上位机节点号、端口、IP地址全部记录下来,谁改谁负责。工控现场最怕的不是技术难题,而是参数对不上。

4. Fins TCP还是UDP?我的选型与调优经验

4.1 TCP/UDP在Fins通讯中的本质区别

Fins TCP和Fins UDP的差别,说穿了就是传输层的差别。TCP有三次握手、确认重传、流量控制,数据可靠,代价是每帧都要维护连接状态;UDP无连接,发出去就不管了,速度快但丢包不负责。

在网络调试助手或Wireshark里看,两者的特征非常明显:

维度Fins/TCPFins/UDP
建立连接先三次握手,再Fins节点握手不需要,直接发FINS帧
可靠性丢包自动重传丢包就丢了,应用层自己处理
报文封装带“FINS”头、长度、命令、错误码只有FINS头部+命令+数据
连接状态长连接,需要维护无连接,来一帧回一帧
应用场景多次读写、跨网段、数据量大的项目实时控制、高速触发,响应快

有意思的是,很多人觉得TCP一定比UDP好,但在Fins通讯场景里不一定。欧姆龙PLC的Fins/TCP连接数量有限,如果上位机每次读写都新建连接再断开,连接资源会耗尽,表现为通讯一段时间后突然失败。所以Fins/TCP要做成真正的长连接,而不是频繁断连。

4.2 长连接与短连接到底怎么理解

这里展开聊一下“TCP长连接与短连接”,因为Fins/TCP实际部署中,这是最常见的设计选择。

短连接就是每一次读写都走“TCP三次握手 -> Fins节点握手 -> 发送命令 -> 接收响应 -> 断开连接”。优点是逻辑简单,但缺点是每次握手都占用时间,而且欧姆龙PLC对同一客户端的连接建立频率有限制,高频次短连接很容易把PLC通讯资源打爆。

长连接则是建立一次连接后,保持不关闭,后续所有Fins读写都在同一条TCP连接上完成。这样吞吐量高、延迟低,工业上位机基本都是这个模式。

但长连接也不是建完就不管了。很多现场遇到“运行一阵子通讯中断”的问题,就是长连接被中间交换机或PLC侧的闲置超时机制掐断了。解决方法是上位机定时发送心跳命令,比如周期性地读一个DM区字,保持连接活跃。心跳间隔按PLC的默认超时时间来定,常见设成2到5秒一包就足够。

我在Fins/TCP长连接里遇到过一种很隐蔽的情况:上位机异常退出,TCP连接没有正常关闭,PLC侧还保留着连接状态,重新启动上位机后发现连接老是失败。解决方式是让重新连接的下位机先连续尝试几次,或者等待PLC的TCP超时自动回收连接。所以在面对“重连失败”时,不要急着改代码,先等几十秒看PLC侧连接是否释放。

4.3 针对VM环境选型建议

在VM虚拟机环境下,我个人的选型经验分两种情况:

如果上位机和PLC在同一台交换机下,网络结构简单、延迟稳定,优先用Fins/UDP。UDP不需要维护长连接,VM里即使网络切换或桥接模式短暂抖动,也不容易把整个通讯状态搞死。很多视觉检测场景都是这种模式,PLC触发相机拍照,视觉软件把结果写回PLC,一来一回就是一帧UDP的事,响应速度很快。

如果上位机和PLC跨了多个交换机、跨了网段,或者中间有防火墙,那就只能选Fins/TCP。TCP绕过NAT和跨网段的麻烦要少很多,而且有重传机制保证可靠。不过要注意,VM里如果开了多个虚拟网卡,要确保Fins流量的端口和IP都绑定到桥接网卡上,不要在NAT网卡上兜圈子。

还有一点是关于VM虚拟机的时钟。TCP时间戳、超时重传对系统时钟敏感,VM如果频繁挂起/恢复,时钟漂移可能导致通讯超时。所以现场长期运行的VM,最好在VMware里关闭“同步虚拟机时间到宿主机”以外的自动挂起功能,或者给虚拟机设置一个稳定的NTP源。这属于VM环境特有的坑,物理机上很少遇到。

5. 抓包与调试:用Wireshark和调试助手快速定位问题

5.1 Wireshark筛选Fins报文的两个做法

抓包工具我基本只用Wireshark。在VM虚拟机里抓包,要选择对应的虚拟网卡接口(比如“VMware Network Adapter VMnet1”或桥接后的以太网接口),然后设置过滤条件。

Fins UDP报文,显示过滤器:

udp.port == 9600

Fins TCP报文,显示过滤器:

tcp.port == 9600

想只看某一台PLC的通讯,可以加上IP过滤:

(ip.addr == 192.168.250.1) && (udp.port == 9600 || tcp.port == 9600)

Wireshark对Fins协议有内置解析,抓到之后在协议列会显示“FINS”,点开能看到ICF、DA1、SA1、命令码等字段,比自己对着十六进制数快得多。如果抓到的包Wireshark没有解析成Fins,而是显示为“Data”,通常是因为端口不是标准的9600,可以在“偏好设置”里手动把Fins UDP/TCP端口改成实际端口。

我个人的习惯是给Fins通讯单独加一个着色规则,比如UDP 9600的包显示为浅蓝色,TCP 9600显示为浅绿色,这样滚动抓包记录时一眼就能看到通讯节奏,有没有断流一目了然。

5.2 UDP前后包时间间隔怎么测

“Wireshark如何筛选出udp前后两包的时间间隔”这个问题,实际调试中用得很频繁。比如排查UDP丢包或者判断响应超时,需要知道相邻两个Fins UDP包之间隔了多少毫秒。

Wireshark默认的“Time”列显示的是每个包相对抓包开始的时间,要看“相对于上一包”的间隔,可以这样做:在Packet Details面板选中某一个包,展开Frame字段,找到“Time delta from previous displayed frame”,然后右键“Apply as Column”。这样表格里会多出一列,每行显示当前包和上一包之间的间隔秒数,单位是秒,比如0.000032就是32微秒,0.512000就是512毫秒。

如果要在命令行里统计,可以用tshark输出该字段:

tshark -r fins.pcapng -T fields -e frame.number -e frame.time_delta -e ip.src -e udp.port -Y "udp.port==9600"

注意Wireshark的显示过滤器不支持“上一包间隔大于X毫秒”这种条件,因为每个包的时间差是计算字段,不是包本身携带的属性。要做这种筛选,要么导出CSV后用Excel处理,要么用tshark加后处理脚本。现场快速看的话,我一般直接看“Delta time”列排序,或者用“统计 -> IO Graph”看每秒包数,曲线异常的地方就是通讯异常的时间点。

5.3 网络调试助手模拟上位机或PLC

很多人把网络调试助手当“万能测试工具”,但用错方向反而会误导排障。以Fins通讯为例,调试助手能做几件很有价值的事:

第一,模拟Fins/TCP客户端连接PLC。新建TCP Client,填PLC的IP和9600端口,连接成功后,手动发送Fins/TCP握手帧。如果PLC回了一个命令码0000的响应帧,说明PLC的Fins服务正常;如果连接被拒或没响应,说明问题在PLC侧或网络侧,而不是上位机软件。

第二,模拟Fins/UDP发送端。把调试助手设置为UDP模式,本地端口任选,目标IP填PLC,目标端口9600,发送一段Fins UDP读命令。PLC会回一个响应帧,收到就能确定协议通。不要忘了ICF字段设为0x80,表示需要响应,否则PLC可能处理了但不会回包。

第三,模拟PLC响应。调试助手开一个TCP Server监听9600端口,上位机软件主动连上来发帧,你就能直接看到上位机发过来的原始Fins帧,用这个方式反推上位机帧格式对不对特别快。这个场景在对接第三方上位机时很常用:先把PLC摘掉,用调试助手假装成PLC,看对方的通讯逻辑是不是符合Fins规范。

调试助手有一个坑要注意:十六进制发送框里,如果直接粘贴带空格的十六进制字符串,多数助手能识别,但有些助手会忽略空格导致字节错乱。我习惯用没有空格的连续十六进制字符串,比如80000200000100000000010182006400010001,宁可长一点也不要让助手解析出问题。

6. 常见问题与排查技巧实录

6.1 问题速查表

把我在VM+欧姆龙Fins项目里遇到过的典型问题整理成一张速查表,现场排查时可以照着对:

现象可能原因排查思路
PLC ping不通虚拟机VM用了NAT或Host-only;桥接绑错网卡改为桥接,指定有线网卡,IP同网段
ping通但Fins连接失败9600端口被防火墙拦截放行虚拟机内Win10的9600端口
连接成功但发命令无响应Fins/TCP没有做节点握手先发命令码0000的握手帧
报“目标节点不存在”DA1节点号和PLC不一致在PLC设置里确认节点号,修改帧中DA1
通讯一段时间后掉线TCP长连接被超时回收用定时心跳读DM区保持连接
UDP发送无响应SA1或DA2配置错误;ICF没有设0x80核对Fins头部所有字段
上位机报端口被占用本机其他软件占用9600netstat查占用进程,换端口
VM重启后通讯失效虚拟机IP变了或桥接网卡复位固定IP,关闭VM网络自动切换

这张表看起来简单,但每一条背后都有真实项目作为支撑。下面说三个让我印象比较深的排障案例。

6.2 三个亲历排障案例

第一个案例是关于VM桥接网卡选错的。项目里PLC挂在有线局域网上,VM虚拟机在笔记本上,笔记本同时连着Wi-Fi。VMware默认把桥接适配器选成了无线网卡,虚拟机IP和有线PLC段完全不搭边,ping都ping不通。当时排查了半小时,最后打开VM设置里的“配置适配器”,把无线网卡取消勾选、只保留有线网卡,问题立刻解决。这个坑在工控现场出现频率极高,尤其是用笔记本调试PLC时。

第二个案例是节点号反复对不上。上位机软件连上了PLC的9600端口,Fins/TCP握手也做了,但每次读DM区都返回错误码0x1103之类的“目标节点不存在”。后来发现,PLC里的节点号被上一个调试人员改成了2,而上位机里DA1一直填的是1。这种问题光看通讯日志很难定位,因为TCP连接正常,只有Fins应用层在报错。所以遇到“能连不能读”的情况,第一反应不是查网络,而是查节点号和单元号。

第三个案例是Windows防火墙明面上开放了9600端口,但Fins/UDP还是收不到响应。我最后逐个排查发现是宿主机上的第三方安全软件把VMware虚拟机进程的网络流量拦了。这个在物理机上很少见;在VM里,流量要经过宿主机的虚拟网卡,安全软件有时会把虚拟网卡流量当成外部入侵来拦截。处理方式是给VMware相关进程加白名单,或者把安全软件对虚拟网卡的防护等级调低。

6.3 最后一公里的排查顺序

多个项目做下来,我总结出一个排查Fins通讯问题的顺序,建议按这个顺序走:

  • 第一步看物理链路:网线、交换机指示灯、PLC和上位机是否在同一台交换机,排除物理故障。
  • 第二步看三层连通:在VM虚拟机里ping PLC的IP。如果ping不通,检查VM网络模式、桥接网卡、IP网段、防火墙ping规则。
  • 第三步看端口连通:用Test-NetConnection或nc测9600端口。端口通,网络层基本没问题。
  • 第四步抓包看协议:用Wireshark抓包,看是否有三次握手、Fins握手、正常读写命令。如果TCP有握手但Fins握手没有响应,重点查PLC节点号。
  • 第五步检查应用层参数:DA1/SA1/DA2/单元号/端口,和PLC侧设置逐一核对。

这套顺序是反着来的:很多人一上来就怀疑Fins协议有问题,然后翻协议文档、改帧格式,结果搞了半天发现是VM用的NAT模式。实际上,链条越靠前的问题越容易定位,先把网络和端口打通,Fins层的毛病反而好查。

最后再分享一个小技巧:在现场给PLC和上位机做IP规划时,把节点号直接取成IP地址的最后一位,比如PLC IP是192.168.250.1,节点号就设1;上位机IP是192.168.250.50,节点号就设50。虽然Fins节点号和IP地址本来没有硬性关联,但这样设置会让人脑的排错成本低很多。我近几年的项目都按这个规则来,Fins参数很少再出低级错误。

如果你也准备或正在做VM和欧姆龙PLC的Fins通讯,希望这份避坑指南能帮你省下几个晚上的加班时间。通讯问题九成以上是网络地基没打牢,先把桥接、IP、端口、节点号这四件事确认清楚,再研究协议本身,就顺了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询