ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

西门子PLC上位机TCP通讯测试实战:从连不通到稳定交付

2026/9/16 1:49:37 拓冰建站 浏览量
西门子PLC上位机TCP通讯测试实战:从连不通到稳定交付 做PLC上位机通讯这么久我最大的感受是配置通了和项目能交付中间还差着一大截。TCP通讯在西门子PLC项目里尤其典型——博图里参数填完、程序编译下载通讯块显示“已建立连接”你以为万事大吉了结果现场一跑三天两头掉线、数据对不上、重启后连不上各种问题全冒出来。所以这个系列我特意留出一篇专门讲TCP测试就是想把这些坑提前暴露在实验室里而不是等项目上线了再被甲方电话叫醒。前两篇分别讲了西门子PLC TCP通讯的指令基础和不同项目组态下的连接配置这一篇是收尾也是最实战的一篇怎么搭测试环境、怎么设计测试用例、怎么通过抓包定位问题包括我自己踩过的几个比较隐蔽的坑一股脑全写出来。不管你是刚接触PLC通讯的电气工程师还是被现场通讯问题折磨过的调试人员这篇应该都能帮上忙。1. TCP通讯排错的第一道关测试前必须想清楚的三件事很多人拿到TCP通讯就开干上位机填个IP、PLC里拖个TSEND_C连上就以为完成任务。但真正到测试环节你会发现如果前期没想清楚几个问题后面排查会特别被动。我每次开始TCP测试前都会先问自己三个问题。1.1 这轮测试到底要验证什么TCP测试听起来只有两个字但目标不同做法完全不同。如果你要验证的是“PLC侧程序写得对不对”那重点就在通讯指令块的参数配置和状态字上——连接能不能建立、数据能不能正确收发、断线后能不能恢复。如果你要验证的是“上位机逻辑和PLC的配合”那重点就变成通讯协议的自定义格式报文头和报文尾、数据长度、校验码是否一致发送和应答的时序是否匹配。如果你要验证的是“长时间运行的可靠性”那就得做压力测试和断网恢复测试不是连上发几个数就完事了。我见过不少同行测试目标没定清楚就开始点按钮结果测了半天只证明了“能通”但项目真正需要的“能稳定运行”根本没验证交付后问题全暴露出来。所以动手测试之前先拿张纸把这轮测试最核心的目标写下来。1.2 问自己谁主动发起连接TCP连接有一方主动另一方被动。在西门子PLC里这个角色是由你在组态里设置的。S7-1200/1500使用TCON或集成了连接管理的TSEND_C/TRCV_C时连接参数里有一个“主动建立连接”的选项PLC作为客户端主动去连接上位机或者PLC作为服务器等着上位机来连。这个选择直接影响测试方式。如果PLC主动连接那上位机测试工具必须处于“监听”状态开着TCP Server等着PLC连过来。如果PLC是被动等待那上位机就要作为客户端去连接PLC的IP和端口。我第一次带新手做测试时最常见的问题就是两边都在等对方连接永远建不起来。建议测试前画一个极简的拓扑图PLC的IP、上位机的IP、谁连谁、端口是多少写清楚再开软件。这个步骤花不了两分钟但能省掉后面一大半的无头绪排查。1.3 测试环境的基本配置一个完整的PLC TCP测试环境至少要包含这些要素要素典型配置说明PLCS7-1200 / S7-1500需要支持标准TCP通讯部分紧凑型CPU需要额外通讯模块上位机普通工程电脑即可建议用有线网卡直连PLC避免无线网络延迟和丢包干扰测试结果交换机或直连网线交叉线或直通线均可现代网卡都支持自动翻转直连一般没问题网络调试工具TCP调试助手 / Python脚本模拟对端的客户端或服务器抓包软件Wireshark当连接建立不了或数据异常时看底层报文是最快的定位手段在实验室里做TCP测试网络环境越简单越好——PLC和电脑用网线直连不经过公司局域网这样可以把网络层面的干扰降到最低。如果必须经过交换机也要确保没有VLAN隔离、端口隔离之类的策略挡住通讯。2. 我的TCP测试工具箱与选型理由做TCP通讯测试工具选对了能省一半力气。我不太推荐上来就用商业成套通讯测试软件虽然功能全但有时候“太重”反而不如几个轻量工具配合着用顺手。下面是我常用的三件套也是我推荐给所有做PLC通讯调试验证的朋友的组合。2.1 免安装的TCP调试助手这类工具市面上很多界面大同小异选择TCP Server还是TCP Client填IP端口连接然后就能发送和接收数据。我手边常备一个免安装版本的调试助手看重的是它“随手能用”这个优点——到了现场不一定有条件装大型软件但一个几百KB的调试助手拷到U盘里双击就能跑。用TCP调试助手做最基础的连通性测试非常方便PLC作为服务器时调试助手选TCP Client填PLC的IP和端口点连接如果PLC侧连接状态变成已建立说明基本通路已经打通。然后你从助手发送一串数据PLC程序里用TRCV_C接收再通过TSEND_C返回一串固定数据助手能收到就完成了最简单的“你来我往”验证。不过调试助手也有明显的短板它的收发是手动操作测一些循环发送、压力场景时不方便而且日志功能普遍比较简单大量数据时会丢失或者显示不完整。所以它只能作为第一阶段的基础工具。2.2 用Python脚本做可控的自动化收发测试当我需要反复发送特定报文、按时间循环发、自动检查应答内容时调试助手就顶不住了。这时候我通常会写一个简单的Python脚本。Python的socket库是标准库不需要额外安装依赖。代码逻辑也不复杂创建一个socket对象connect到PLC的IP和端口然后循环发送预先构造好的字节串每收到一帧数据就记录时间戳和内容最后输出统计结果。比如我经常这样构造一个循环发送的测试脚本核心部分import socket, time HOST 192.168.0.1 # PLC的IP地址 PORT 2000 # PLC监听的端口 # 构造一帧测试报文前两个字节是长度后面是数据正文 def build_frame(payload: bytes) - bytes: length len(payload).to_bytes(2, byteorderbig) return length payload s socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(3) s.connect((HOST, PORT)) payload bytes.fromhex(01 03 00 00 00 0A) frame build_frame(payload) for i in range(1000): s.sendall(frame) resp s.recv(1024) print(fseq{i}, recv{resp.hex()}) time.sleep(0.1) s.close()Python脚本的好处是可控性强想发1000帧就发1000帧想每100毫秒发一次就每100毫秒发一次想记录每帧的时延就记录。这些是手动操作根本做不来的。对于S7-1200/1500通讯压力测试和长时间稳定性测试Python脚本远比调试助手高效。2.3 Wireshark最后一道关键防线当前面两个工具都查不出问题时就要靠Wireshark了。抓包分析是TCP调试的最终判断手段因为不管上层软件显示什么网络报文是客观存在的每一帧都能在Wireshark里看到。用Wireshark抓PLC通讯包时我一般会设置过滤器只关心PLC的IP和端口避免大量无关广播包干扰视线。比如只抓PLC IP地址为192.168.0.1的流量ip.addr 192.168.0.1在这个过滤条件下你可以清楚看到TCP三次握手的过程SYN、SYN-ACK、ACK。如果连握手都完成不了说明物理链路或防火墙有问题。如果握手成功但数据收发不对就要看报文内容里的字节序、长度字段和数据格式。有时候上位机显示“发送成功”但抓包发现报文根本没到网卡或者报文的源IP压根不对这就是程序逻辑的深坑了。2.4 工具的配合逻辑这三个工具怎么配合我有几条判断标准链路是否通、端口是否通、基本收发是否正常 → 用调试助手快速验证。需要自动循环、批量验证协议格式、测压力 → 用Python脚本。通讯完全不通、数据错乱、排查不出原因 → 抓包分析用Wireshark看底层真实报文。从调试助手的“摸黑操作”到Python脚本的“批量验证”最后到Wireshark的“眼见为实”层次是递进的。多数问题在前两层就能定位Wireshark是兜底方案但一旦用到它定位几乎都是一针见血。3. 手把手跑通一轮PLC TCP通讯测试这部分我就以S7-1200 PLC和上位机之间的TCP通讯为例把从零到通的完整流程走一遍。这些操作我在多个项目里反复验证过你照着做大概率能直接复现。3.1 网络基础检查别在最基本的地方翻车接通物理线缆后第一件事不是打开博图而是先确认网络底层的连通性。用上位机的命令行工具ping一下PLC的IP地址。假设PLC的IP是192.168.0.1上位机是192.168.0.10执行ping 192.168.0.1能收到回包说明二层三层链路已经通了可以进入协议层测试。ping不通先查IP是否在同网段、网线是否完好、PLC的PROFINET接口是否启用了正确的IP这些排查要在协议层之前做完。有个细节经常被忽视电脑如果有无线网卡和有线网卡同时连接操作系统路由表可能出问题导致发往PLC的报文走了错误网卡。这种情况下ping会偶尔通偶尔不通或者完全不通。最简单的方法是禁用无线网卡只保留有线连接或者手动指定到PLC网段的路径确保测试环境的纯粹性。3.2 PLC侧的准备工作DB块、连接参数与指令块在博图项目里新建或打开你的PLC程序需要准备这几个部分。建立发送和接收数据区。我习惯建两个DB块一个用于发送数据一个用于接收数据。每个DB里包含一个长度变量和一个数据数组数组使用Byte类型长度根据通讯内容设置建议留出足够余量。比如发送64个字节数组就定义成64个Byte。组态连接并配置连接参数。如果你用的指令是TSEND_C或TRCV_C带连接管理的版本需要在块参数里配置一个DB作为连接描述。以TIA Portal的S7-1200为例新建一个全局DB在其中添加一个类型为TCON_IP_v4的结构变量这是最常用的连接描述结构。关键字段包括InterfaceIDCPU网口的ID一般填64对应PROFINET接口。ID连接ID整个项目必须唯一不能和其他连接重复。ConnectionType16表示TCP连接。ActiveEstablishedTRUE表示PLC主动连接FALSE表示PLC等待连接。RemoteAddress对端IP地址即上位机的IP。RemotePort对端端口比如上位机监听2000。LocalPort本地端口比如PLC使用2000。这里我要强调一下ID的唯一性。如果你一个项目里创建了不止一个TCP连接每个连接的ID绝对不能一样否则连接会互相冲突严重的会出现通讯块报错甚至CPU找不到连接资源。我排查过几次“多项目移植后通讯失败”的问题最后根因都是ID复制粘贴后忘了改。调用指令块。在OB1或者循环中断OB里调用TSEND_C和TRCV_C。TSEND_C用于发送TRCV_C用于接收它们的使能输入需要循环触发不能只置TRUE一次——这也是常见的逻辑错误点。一般我会用一个常ON的M点或者用系统时钟位来做使能保证每个扫描周期都尝试收发。如果使用单独的TCON、TSEND、TRCV、TDISCON指令则需要自己管理连接建立和断开的状态机相对更复杂但灵活性更高也更适合“不同项目下的TCP通讯”这种需要频繁切换连接对象的场景。这里有个细节值得展开说TSEND_C和TRCV_C的好处是连接内置管理但坏处是每个指令块只绑定一个连接参数如果你想动态切换目标IP就得用TCON/TSEND分离的方式。所以选指令之前先想清楚项目中是不是存在“一台PLC需要和多个上位机轮流通讯”的需求。3.3 上位机模拟器的连接流程PLC侧程序下载运行后在上位机上打开TCP调试助手。如果PLC配置的是被动接收PLC作为服务器等待连接调试助手就需要设置为TCP Client模式填入PLC的IP和PLC监听端口比如2000点击连接。此时观察PLC程序里TRCV_C的Status或连接管理块的输出应该能看到连接状态变为ESTABLISHED。如果PLC配置的是主动连接PLC作为客户端调试助手上要设置成TCP Server模式监听规划的端口比如2000然后等待PLC连过来。为方便测试建议上位机的IP和端口要和PLC连接描述中的RemoteAddress和RemotePort保持一致。连接建立后先从上位机发一串数据在PLC里观察接收DB的内容看数据是否正确落在接收数组里。然后再通过PLC的发送块回传一串数据上位机端检查收到的内容。这个双向回环测通TCP通讯的基础功能就算验证完成了。3.4 数据内容对不上的字节序问题验证TCP测试里有个很容易让人头大的现象连接完全正常数据也收到了但内容就是不对。比如PLC发送的整数到了上位机变成一串乱码或者上位机发的浮点数PLC解析出来完全不是预想的值。这类问题十有八九是字节序或者类型长度不一致导致的。西门子PLC使用大端字节序也就是说一个16位整数0x1234在报文里先传0x12再传0x34。但很多基于x86架构的上位机程序默认是小端序如果不做转换读到的就是0x3412数值完全变了。浮点数更麻烦不仅有字节序问题还涉及IEEE 754格式的对齐。在这个阶段要做的验证是用调试助手或Python脚本发送一串已知内容的十六进制数据帧比如发送01 02 03 04 05 06然后看PLC接收DB里是什么。如果接收数组完整显示这六个字节说明链路数据正常。接着再测试字和浮点的对应关系确认上位机和PLC对数据的解析方式完全一致再进入正式协议开发。4. 测试用例设计不单测“通没通”还要测“抗不抗造”很多工程师接触TCP测试测来测去就是“能连上”、“能发数据”、“能收数据”然后就觉得完事了。但作为系列第三篇我想把测试用例设计这个关键环节单独拿出来讲清楚——因为项目的可靠性恰恰是在这些“多余”的测试里出来的。4.1 基础连通性测试所有测试的第一步验证连接能不能建立。用例设计的重点不止是“能”还要量化连接建立用了多长时间从下发连接请求到Status变为已建立应该在几百毫秒以内连接断开比如拔网线多久后被系统检测到默认的保持激活机制KeepAlive如果没有配置可能要在TCP超时后才能发现断线这个时间可能是分钟级甚至更长。测试时记录这些时间参数对后续设计断线重连逻辑非常有用。假如不做这个基础测试就直接开发重连逻辑你根本不知道该设置多长的重连周期。4.2 边界与协议验证通讯协议设计完成之后需要测试几个常被忽略的边界场景超长报文测试PLC的TCON最大数据长度是有上限的比如很多S7-1200系列CPU单次TCON最大数据长度是8192字节但项目和项目不同所以测试时要把发送长度加到接近上限的位置确认系统不会因为长度超出而静默丢弃数据。建议分别测试500字节、1000字节、2000字节的报文。零长度报文有些上位机程序在特殊逻辑下会发送空报文字段PLC收到后会不会报错TRCV_C是否返回错误代码如果协议里没有对空帧做处理可能导致通讯卡死。粘包测试TCP是流协议没有消息边界。如果上位机连续发送两帧数据PLC接收程序能正确地把它们识别为两帧而不是粘成一帧吗这需要通讯协议考虑加报文头、长度字段或者帧结束符。测试用例里专门模拟一次高速连续发送很容易暴露出边界划分问题。超时与重试设置极小的时间间隔间断地发送数据PLC侧接收并立即响应上位机的应答超时时间是否合理超时后是否有重发机制这个对项目现场意义重大尤其是上位机经过网闸、路由器等设备时网络延迟可能比实验室大得多。4.3 异常场景测试断线重连与恢复这是TCP测试中最有价值也最容易被跳过的部分。第一个场景通讯过程中直接拔掉网线过10秒再插回去PLC和上位机能否自动恢复连接很多项目用TSEND_C/TRCV_C如果连接参数中没有合理的自动重连机制拔网线后连接状态会一直挂着即使网线恢复也不会主动重连必须重启PLC或者重新触发生成连接。这个测试直接决定了你的项目交付时用户拔错网线之后系统能不能自愈。第二个场景PLC重启。上位机程序是不停运行的PLC断电再上电后上位机能否主动重连如果上位机逻辑里只有一次connect那PLC重启后连接就再也回不来了。用例要验证PLC从断电到恢复的完整过程包括上位机检测到连接断开的时间、重连尝试的间隔、最终连接恢复的时间。第三个场景上位机程序崩溃后重启。这相当于Client端主动断开PLC侧的连接状态是否被正确清理如果PLC里的连接资源被耗尽就会出现“上位机重启但连不上PLC”的现象。4.4 多客户端连接资源测试很多项目不是单台上位机连PLC而是中控室有两台、现场还有一台触摸屏或工程师站大家都往PLC上开TCP连接。不同PLC的TCP连接资源数量是有上限的S7-1200一般支持8个左右的TCP连接具体看型号固件S7-1500也不一定是无限连接总有资源上限。我就遇到过现场有两台上位机正常工作第三台接入后发现第一二台偶发掉线的状况——连接资源满了新连接挤掉了老连接。多客户端测试在项目交付前一定要做至少模拟两台以上客户端同时连接PLC每台都循环收发数据持续一段时间确认没有资源冲突。如果你的项目确实需要很多客户端同时接入就得考虑给PLC换更高型号或者用网关做转发。5. 一次真实排查实录握手成功但数据不刷新前几节是方法论这一节我讲一个真实的排查过程。这起故障的排查思路可以套用到大多数TCP通讯异常场景中。5.1 现象连接正常数据不动当时的项目是PLC和上位机做Modbus TCP通讯。上位机显示连接已建立没有任何报错但实际数据就是纹丝不动——PLC寄存器里的温度值变了上位机画面上还是旧值。这种“软故障”特别容易让人烦躁连接是好的没有报错但就是功能不对。很多人会原地打转一遍遍看程序逻辑。5.2 抓包连接没毛病报文有蹊跷我做的第一件事是在上位机上用Wireshark抓包。过滤器设置为上位机与PLC之间的流量很快定位到异常三次握手正常Modbus TCP报文Address单元标识符和Function Code都正确数据请求也发过去了PLC也回了TCP层的ACK。但问题在于——PLC返回的响应报文里内容长度字段与实际数据长度对不上导致上位机的解析程序认为这是非法响应直接丢弃了。从应用层看连接是“好的”从协议层看通讯数据是错误的。如果不抓包光靠上位机的通讯状态指示灯这个问题永远查不出来。5.3 根因命令触发常开导致阻塞继续排查为什么PLC返回的报文长度字段异常。检查PLC程序后发现问题出在触发方式上Modbus TCP服务器指令的触发被写成了常TRUE导致同一个请求在每个扫描周期都被重复触发。CPU处理不过来时内部的请求缓冲区就会被反复填充最后返回的响应报文被截断或者拼接出错长度字段自然对不上。修复方式很简单把常TRUE触发改成沿触发上升沿只在一个请求流程完成后才允许下一个触发同时在通讯指令前方增加一个“上一条指令完成”的互锁逻辑保证同一个请求不会重叠执行。5.4 从这次排查中总结出的思路这次之后我给自己定了一条排查规则当TCP连接正常但数据异常时不要在应用层死磕直接从抓包开始看协议报文。抓包能告诉我们事实——连接建立与否、字段是否正确、长度是否匹配——然后根据事实反推问题在PLC侧还是上位机侧。这个顺序在多数情况下都能快速收敛问题范围比盲目猜测效率高得多。6. 几个测试时容易踩的隐形坑最后再写几个我踩过的坑每一个都曾经让我多花过半天到一天的时间去查。6.1 防火墙拦截连接超时还是被丢弃上位机的Windows防火墙经常默认拦截陌生程序的入站连接。有时候你开着TCP调试助手数据显示“连接中”然后一直连不上极有可能是防火墙在静默丢包连拒绝都不会提示。排查方法很简单抓包看有没有回包如果上位机能发出SYN但收不到SYN-ACK除了PLC侧问题也要检查本机防火墙规则。测试直接把程序的入站规则放行或者临时关闭防火墙仅限实验室环境能排除这个干扰项。6.2 调试助手的HEX显示陷阱很多网络调试助手的接收区默认用ASCII显示数据里的非可打印字符显示成乱码或者空白看起来就像“没收到数据”。测试时一定要先把收发窗口切到HEX显示特别是调试二进制协议时。我见过有人在ASCII模式下对着乱码研究了半小时切到HEX后一眼就看出数据其实完全正确。这虽然是个小细节但能让你的调试效率有质的提升。6.3 项目移植后的连接ID冲突这个坑在“不同项目下”的TCP通讯中尤其明显。从一个项目复制程序到另一个项目时容易把原来的连接ID一起带过来。如果两个项目共用同一个PLC或者两台PLC的IP和连接描述没有修改就会产生冲突。我处理过一起案例A项目程序下载到PLC后一切正常B项目程序下载上去后原本A项目的通讯突然断了——检查发现两个项目用了相同的连接ID和端口。PLC固件里连接资源是全局的不会因为项目不同而自动隔离。这个问题的规避方式很简单每次移植项目时都手动检查连接描述DB里的ID、IP、端口这三个参数确认没有和现网设备冲突。6.4 长时间运行后的资源耗尽短时间功能测试通过不代表项目能长期运行。TCP连接资源耗尽是一个隐蔽的慢性病连接建立、断开再建立、再断开系统里的TIME_WAIT状态连接没有及时释放资源慢慢被占满最终上位机无法发起新连接。测试时如果你发现断线重连测试中前几轮重连都很快后面越来越慢最后直接连不上——八成就是连接资源没有正确释放。排查时抓包看断开过程是否有FIN/RST的完整交互Wireshark里如果有大量TIME_WAIT状态的连接基本可以断定问题在这里。解决方案通常是调整上位机socket的重用地址选项SO_REUSEADDR或者检查PLC侧连接指令的断开逻辑是否被正确触发。6.5 别把“连上”当作“没问题”最后这条是我最想强调的TCP连接建立成功只能证明底层链路和端口是通的完全不代表通讯协议正确、数据可靠。很多项目在测试阶段只验证到“连接正常”就交付现场一有数据错误就开始推卸责任其实问题在协议设计阶段就已经埋下了。建议在项目里引入简单的数据校验机制比如Modbus TCP的CRC校验、自定义协议里的累加和校验、帧序号和时间戳这些能在数据链路出错时快速发现问题。TCP保证的是包送达和顺序不保证业务数据完全正确尤其经过复杂的网络拓扑时脏数据、错数据难免出现。测试阶段就把这些场景覆盖到到现场才有底气。根据我这些年做通讯调试的经验TCP测试最核心的心得就是测试不是证明“能通”而是要让设备在不可靠的网络环境中尽可能可靠地工作。基础连通只是起点异常断线恢复、多客户端并发、字节序一致性、长时运行资源释放——这些才是真正决定项目交付质量的测试项。当年我被现场各种通讯问题折磨得够呛后来养成了一到实验室就把网络环境往“恶劣”里测的习惯反而让后续的项目变得越来越省心。希望这篇TCP测试经验能帮你把该踩的坑提前踩完测试阶段多花的时间在现场都会加倍还回来。