
大概在半年前我接到一条装配线的改造任务。现场情况是产线上有80个托盘每个托盘底部嵌着一张RFID标签托盘经过不同工位时PLC要实时读出托盘上挂的车型信息自动切换拧紧扭矩和物料清单。主控用的是汇川AM401触摸屏用的是汇川IT系列。最开始大家想走的是RFID读写器最常见的Modbus RTU串口方案因为大部分读写器都支持PLC这边也支持串口自由口通讯感觉改起来会很快。可现场走了一圈问题全暴露出来了。RS485线从第一个读头到PLC控制柜接近50米加上中间分线整个链路串了四五个读头总长度超过120米。9600bps波特率勉强能通但偶尔丢帧把波特率拉到19200bps通讯直接不稳定。更要命的是装配线是边走边读留给PLC读取标签的时间窗口只有大约300毫秒Modbus RTU那种查询-应答一问一答的方式根本来不及。后来我把方案整个换成CK-LR08-E00工业级RFID读写器走以太网用TCP/IP自由协议和汇川PLC直接通讯问题一次性解决。这篇就把完整的选型思路、报文设计、PLC程序结构和现场调试过程讲透给打算做RFID和PLC以太网自由协议通讯的人一个可以直接抄作业的实例。1. 为什么是自由协议而不是Modbus TCP一条装配线改造的通讯选型复盘1.1 现场最初的方案评估在做方案的时候我把市面上的通讯方式都过了一遍。除了Modbus RTU串口还有Modbus TCP、TCP/IP自由协议、IO触发这几种路线。加起来大概四个方案我一一盘过最后才定下来走自由协议。先看Modbus RTU串口这个方案最大的优势是便宜通用几乎每个读写器都带RS485口汇川PLC这边的配置也不算复杂。但它的短板太明显速度被波特率卡死距离被线缆质量卡死抗干扰能力在电柜密集的场合又是个隐患。我们一条线上要挂四五个读头全部走串口串联任何一个节点出问题整条链路都会受影响排查起来特别费劲。再看Modbus TCP通讯速度解决了PLC也有现成的库可以用。但真正写程序的时候你会发现Modbus TCP的数据是映射到一组保持寄存器里的标签数据不定长、还是突发性的PLC要做批量轮询、还要处理寄存器刷新时机绕了一圈反而比自由协议更麻烦。而且像EPC这种12字节以上的原始数据用Modbus寄存器表达特别别扭先得把字节序倒腾一遍触摸屏那边还得再倒腾一遍中间的坑多得离谱。IO触发方案最简单只能告诉PLC标签有还是没有具体内容完全拿不到。对只做防错的工位可能够用但对需要识别车型、切换工艺参数的产线来说完全不够。最终选TCP/IP自由协议核心就一句话汇川AM401在Codesys平台下可以直接用Socket套接字收发任意字节CK-LR08-E00也开放了TCP Server端口允许用户自定义报文两边都有直接操作字节流的能力那为什么还要套一层Modbus中转直接在PLC里拼命令、发命令、收报文、解析EPC所有逻辑都看得见摸得着出问题也能快速抓包定位。下表是我当时做的对比供参考。方案优点缺点适合场景Modbus RTU串口成本低、读写器普遍支持速度慢、距离受限、抗干扰一般读头少、距离短、节奏慢的工位Modbus TCP标准协议、PLC库成熟数据寄存器映射繁琐、不定长数据表达别扭现场已有Modbus经验、上位机也要取数据的场景TCP/IP自由协议报文可控、直接返回原始标签数据、灵活性最高需要自己约定协议和CRC校验标签数据需要快速进PLC、读写器开放自定义TCP口IO触发最简单、成本最低只能传达有/无信号读不到标签内容只做防错校验的简单工位1.2 自由协议需要注意的自由边界选自由协议不是说报文可以随便写。真正的难点在于自由协议的一切约束都靠两端自己去约定没人帮你兜底。协议定了之后帧头要一致、长度字段的大小端要一致、CRC校验覆盖范围要一致、超时重发机制要一致任何一处不一致结果就是PLC收到一堆乱码或者干脆没反应。我见过不少项目一听到自由协议就觉得自由了组帧随便写长度字段想放哪个字节就放哪个字节结果联调的时候两边一直在扯皮。我的习惯是动PLC程序之前先把报文格式用一张表定死截图发给读写器厂家确认一遍再动手写代码。确认错了最多浪费半天不确认就写后面可能白白搭上好几天。1.3 网络拓扑和数据链路设计整个系统是标准的工业以太网星型结构。CK-LR08-E00读写器接到现场工业交换机汇川AM401 PLC接在交换机另一个口上触摸屏也在同一个交换机。网段规划成PLC是192.168.1.10读写器是192.168.1.200触摸屏是192.168.1.30网关统一指向192.168.1.1。读写器配置为TCP ServerPLC作为TCP Client主动建立连接这样PLC对连接的生命周期有完全的控制权读写器断电再上电后PLC可以自己判断重连时机。数据链路分两层理解。物理层是天线—读写器—网线—交换机—PLC网口逻辑层则是一条PLC发送读标签命令帧读写器返回应答帧PLC按协议解析出EPC和RSSI标签数据写入变量供HMI显示和后续逻辑使用的消息流。后面每一环怎么配、怎么写、怎么调我一个一个拆开讲。2. CK-LR08-E00读写器侧的准备IP配置与报文格式约定2.1 硬件接线与上电前的注意点先说硬件。CK-LR08-E00是一台工业超高频RFID读写器支持ISO18000-6C协议工作频段覆盖920到925MHz这个国内常用频段配一个SMA接口的外置天线供电是DC24V带一个RJ45百兆网口。我拿到的样机固件版本是V2.3设备管理界面和指令集在不同批次上会有小幅差异但大的配置点基本一致。接线有几点必须注意。第一天线馈线能短就短。SMA馈线超过3米后信号衰减非常明显实测读取距离会缩短两成以上我这边的馈线尽量控制在1米内。第二天线正前方和侧面不要有连续金属平面尤其是金属托盘循环线这种场景天线与金属面之间至少要留出200mm以上否则反射波叠加会出现盲区标签到了盲区就怎么都读不到。第三读写器供电最好单独给一路DC24V开关电源不要和变频器伺服共用电源。读写器瞬间发射射频时电流会有一个跳动电源不干净很容易把干扰引到通讯电路上。第四上电前先把天线接好再接电SMA接口尽量不要空载尤其大功率输出时空载容易损坏射频功放。2.2 配置IP地址和工作模式读写器默认IP一般和PLC不在同一个网段第一次使用需要用随机附带的搜索工具按设备MAC地址或扫描网段把设备找出来修改IP后重新分配固定地址。我这台默认是192.168.1.168因为要和PLC的192.168.1.10通信改成了192.168.1.200子网掩码255.255.255.0网关统一指向192.168.1.1。修改之后读写器会自动重启重启完网段才生效。接着设置工作模式。CK-LR08-E00内置了好几种工作模式我选的是被动应答模式也就是由PLC主动发命令读写器收到命令后才执行并返回结果。另有一种主动上报模式读写器一检测到天线场内有标签就自己往上发数据好处是PLC不用轮询坏处是数据到达时机不可控。装配线上一个工位可能同时进来好几个托盘主动上报模式会出现连续好几帧报文一股脑砸过来PLC处理起来要额外做队列和状态管理程序复杂度会明显上升。为了保持逻辑可控我选了被动应答。通讯设置里把通讯方式设成TCP Server固定监听端口8600允许的最大TCP连接数设为1。一读头对应一PLC一个连接足够了。如果有多台PLC要同时取数据读写器一般不支持多连接得加串口服务器或者用上位机转发那是另一种架构了。2.3 报文格式约定帧头、命令、长度、CRC和帧尾自由协议的关键在于先约定好再写程序。下面这套报文格式是我实际在用的可以直接参考。先看PLC发给读写器的命令帧固定结构如下偏移字段宽度说明示例值0帧头1字节固定AAAA1帧头1字节固定55552命令码1字节01读EPC02写EPC03读TID013数据区长度高字节1字节大端高字节在前004数据区长度低字节1字节大端005 起数据区n字节命令参数空5nCRC高字节1字节CRC16-Modbus覆盖从偏移0开始到数据区结束的字节xx6nCRC低字节1字节CRC结果高字节在前xx7n帧尾1字节固定1616最常用的读EPC命令没有数据区边长8字节十六进制长这样AA 55 01 00 00 xx xx 16其中xx xx是根据前面5个字节AA 55 01 00 00算出来的CRC16-Modbus校验值。再看读写器返回给PLC的应答帧结构基本一致只是命令码变了。读EPC的应答命令码固定为0x81数据区第一个字节是状态字0x00表示成功其他值是错误码后面跟着12字节的EPC数据。因为多了12字节的EPC数据区长度就是13字节也就是0x000D。一个典型的读EPC应答帧长这样AA 55 81 00 0D 00 E2 80 11 60 12 34 56 78 9A BC DE F0 xx xx 16其中AA 55是帧头81是应答命令码00 0D表示数据区长度13字节第一个00是状态字从E2到F0这12个字节是标签EPCxx xx是CRC16是帧尾。这里有一个最常见的坑CRC16的覆盖范围到底从哪里到哪里。不同厂家的习惯不一样有些厂家把帧头也纳入校验有些厂家从命令码开始校验。我这台CK-LR08-E00的固件是按从帧头AA开始到数据区最后一个字节结束不包括CRC本身和帧尾来算的。这块如果不跟厂家确认清楚后面CRC会一直对不上。2.4 为什么我让PLC做Client读写器做Server很多人在做TCP自由协议时习惯把设备端设为Client让PLC当Server等对方连过来。我在工业现场不这么干。让PLC主动做Client有两个直接好处。第一PLC可以在上电后自己判断什么时候建立连接。读写器上电到TCP Server起来一般需要一两秒PLC如果一通电就去连大概率连不上需要重连逻辑。PLC做Client时这个重连逻辑非常好写主动权完全在自己手里。第二当网络异常断开时PLC能控制重连节奏避免读写器断电期间PLC一直在发连接请求把网络塞满。另外从排查角度讲PLC发起连接后读写器日志里会清楚记录某个IP在某个时间发起了TCP连接PC端抓包也能很清楚地看到连接三元组问题定位快很多。当然这个前提是读写器支持固定IP且能做TCP Server监听。CK-LR08-E00支持所以成立。如果遇到只支持Client的设备PLC就必须自己监听端口等连接进来程序里还要处理多个连接抢占问题复杂度会明显上一个台阶。3. 汇川PLC侧的程序实现Socket连接与收发状态机3.1 在InoProShop里搭出Socket通信基础框架汇川AM400/AM600系列用的编程软件是InoProShop基于Codesys平台底层用ST语言写逻辑。网络通信库在库管理器的通信分类下能找到不同版本的库名字有差异我这边库版本较新里面带的是TCPSocket这类功能块。核心用到的功能块大致有四个SocketConnect或TcpConnect作为TCP Client主动发起连接输入服务器IP和端口输出连接句柄和连接状态。SocketSend把要发送的字节数组发送到指定连接句柄。SocketRecv从指定连接句柄接收字节存入接收缓冲区。SocketClose关闭指定句柄。用这些功能块有个非常重要的习惯它们大多采用Execute边沿触发不能把执行位一直置成TRUE否则功能块会一直反复执行。我是用一个触发变量每次需要建立连接或发命令时给Execute一个FALSE到TRUE的上升沿等Done信号出现后再复位。这个习惯帮我省了大量调试时间。3.2 主状态机从连接到断线重连的全流程自由协议没有标准协议那种自动管理连接的机制我强烈建议把整个通信过程做成状态机不要用从上到下扫一遍的线性PLC程序。我定义的状态如下S_INIT 0; // 初始化等待 S_CONNECT 1; // 发起TCP连接 S_READY 2; // 连接建立成功空闲待命 S_SEND_CMD 3; // 发送读标签命令 S_WAIT_RESP 4; // 等待读写器应答 S_ERROR 5; // 通信异常准备重连程序主循环里按当前状态执行对应逻辑。上电后进入S_INIT延时1秒让读写器完成TCP Server初始化然后进入S_CONNECT调用SocketConnect主动连接192.168.1.200:8600。连接成功后进入S_READY此时如果托盘到位信号触发就进入S_SEND_CMD发送读EPC命令发完立刻转到S_WAIT_RESP并开启一个500ms超时定时器。若在超时时间内收到完整且CRC校验通过的应答帧就解析数据、更新标签变量、回到S_READY若超时没收齐重发计数加1回到S_SEND_CMD重新发命令连续重发3次都失败判定通信异常进入S_ERROR主动关掉Socket延时2秒后回到S_INIT准备重连。这个状态机把正常读取、偶发超时重试、完全断线重连三条路径都覆盖了是我在不同项目里反复调试后定型下来的结构。你复制过去改改IP和端口就能用关键在于这套结构不会因为某次通信失败就把PLC程序卡死。3.3 CRC16校验的ST实现CRC16-Modbus是整个帧校验的核心。我常用的ST函数如下注意最后做了字节交换因为协议约定CRC高字节在前FUNCTION F_CRC16_MODBUS : WORD VAR_INPUT pData : POINTER TO BYTE; dwLen : DWORD; END_VAR VAR uiCRC : WORD; iByte : DWORD; iBit : INT; END_VAR uiCRC : 16#FFFF; FOR iByte : 0 TO dwLen - 1 DO uiCRC : uiCRC XOR WORD(pData[iByte]); FOR iBit : 0 TO 7 DO IF (uiCRC AND 16#0001) 0 THEN uiCRC : (uiCRC SHR 1) XOR 16#A001; ELSE uiCRC : uiCRC SHR 1; END_IF; END_FOR; END_FOR; F_CRC16_MODBUS : (uiCRC AND 16#00FF) SHL 8 OR uiCRC SHR 8;组帧时把收发数组的首地址传给pData长度按从AA开始到数据区结束计算。这里有个关键点校验范围一定要和读写器固件文档核对清楚。我在不同项目里遇到过从命令码开始校验的、甚至有的从数据区开始校验的五花八门。所以拿到读写器后的第一件事就是拿官方示例报文逐字节验证CRC算法对上了再写进PLC程序。省这一步后面CRC出错时你会浪费两三天。3.4 接收缓冲TCP协议天然会带来的粘包和拆包TCP是面向流的底层不保证每次recv到的数据刚好等于发送方的一帧。读写器连续返回两帧应答时可能一次性把两帧塞给PLC这叫粘包一帧应答也可能被拆成两三个小包分次到达这叫拆包。如果PLC程序收到数据后直接按一帧解析遇到粘包或拆包就全乱了。我处理的标准做法是维护一个接收字节数组缓冲把SocketRecv收到的字节不断追加进去然后做找帧头、读长度、收整帧、验CRC的解析。流程分三步第一步在缓冲里寻找连续的两个字节0xAA 0x55。如果没找到把缓冲清理掉等新数据。找到后从帧头开始往下读偏移3和偏移4的两个字节作为数据区长度n。第二步检查缓冲里从帧头开始是否已经有n8个字节。这n8是帧头2字节加命令码1字节加长度2字节加数据n字节加CRC2字节加帧尾1字节算出来的。如果不够说明这一帧还没收完整继续等下一轮recv。如果够了把这n8个字节整帧取出做CRC校验。第三步CRC不对就丢弃帧头第一个字节从下一个字节重新找0xAA 0x55继续解析。CRC正确就把整帧交给上层解析函数提取状态字和EPC。这样处理之后无论TCP底层怎么粘怎么拆PLC程序都能稳定取出一个完整且校验正确的报文帧。这套逻辑我在多个项目里复用过是自由协议通讯里最值得认真写的一部分比任何命令字和设备库都重要。4. 联调实录抓包、解析与HMI联动的完整流程4.1 先用电脑模拟PLC验证读写器报文是否符合预期把PLC正式接进去之前我都会先做一步电脑假扮PLC的联调。这一步非常关键等于先把问题隔离在网络协议层而不是让PLC程序问题和网络问题搅在一起。在电脑上开一个网络调试助手或者直接用Python写几行脚本连到192.168.1.200:8600发送读标签命令看返回什么。最简单的一段测试脚本如下import socket def crc16(data): crc 0xFFFF for b in data: crc ^ b for _ in range(8): if crc 0x0001: crc (crc 1) ^ 0xA001 else: crc 1 return ((crc 0xFF) 8) | (crc 8) cmd bytes([0xAA, 0x55, 0x01, 0x00, 0x00]) cmd crc16(cmd).to_bytes(2, big) cmd bytes([0x16]) s socket.create_connection((192.168.1.200, 8600), timeout3) s.sendall(cmd) resp s.recv(1024) print(resp.hex()) s.close()如果读写器天线前有标签脚本会打印出一串十六进制通常长这样aa5581000d00e2801160123456789abcdef0xxxx16把返回的报文和手册示例逐字节对一遍确认帧头、长度、状态字、EPC位置都能对上。这一步做完说明读写器工作正常通讯协议也基本正确再进入PLC联调就轻松了。4.2 首次联调记录三个真实遇到的小问题第一次把PLC程序启起来我实际碰到了三个问题这里逐条记录都是特别典型的小坑。第一个问题是PLC连不上读写器。排查下来是IP写错了。读写器IP已经改成了192.168.1.200但PLC程序连接目标地址我写成了192.168.1.2少了一位0。改回来之后立刻能通。这种低级错误光靠眼睛检查很难发现最好的办法就是抓包或者Ping一下把地址确认清楚再往下走。第二个问题是连接能建立但读写器对命令没反应。抓包发现PLC确实把AA 55 01 00 00 xx xx 16发出去了但读写器根本没回包。后来排查发现端口号不一致读写器配置软件里监听端口设的是8600PLC程序里连接端口写成了6080。这种IP看着对但端口错的问题在没有抓包习惯时特别容易卡壳因为Ping是通的你以为网络没问题实际上TCP根本连错门了。第三个问题是返回包CRC老是校验失败。同一个命令电脑端测试正常换到PLC程序里就CRC失败。对比两组报文命令字节完全一样问题出在接收解析PLC程序在算CRC时把帧尾0x16也算了进去而读写器的CRC是不包含帧尾的。把校验长度减掉一个字节问题立刻消失。这三个问题都不难但每次联调几乎都会碰上一两个。所以我现在总结出一个固定习惯先跑通电脑端再接PLC出问题先抓包不要靠猜。4.3 Wireshark抓包怎么看TCP报文里的RFID数据调试以太网通讯时Wireshark是必开工具。在PLC和交换机之间加一个镜像端口或者在笔记本上连到同一台交换机做端口镜像启动抓包后过滤tcp.port 8600就能看到PLC和读写器之间的全部TCP报文。抓包重点看三层。第一层是TCP三次握手SYN、SYN-ACK、ACK三个包正常出现说明TCP连接建立没问题。第二层是应用层数据在Wireshark中部窗口的Transmission Control Protocol里往下找TCP Payload能直接看到AA 55开头的十六进制数据这就对应了PLC发出的命令帧或读写器返回的应答帧。第三层是TCP序列号和重传情况如果看到大量TCP Retransmission或Dup ACK说明现场网络有丢包或交换机性能不足这种情况下RFID数据再对也是白搭。需要特别说明Wireshark只反映网络层字节内容它不会帮你做CRC校验。看到报文数据之后还是要靠PLC程序按协议解析。不过Wireshark能快速帮我们判断问题属于设备根本没发数据还是发了但PLC解析错了这两类情况中的哪一种这已经能省掉一半排查时间了。4.4 HMI联动和最终读写成功率验证标签数据进PLC后我把它映射到一组全局变量方便触摸屏读取szTagEPC : ARRAY[0..11] OF BYTE; // 12字节EPC按十六进制显示 wRSSI : WORD; // 信号强度 bTagRead : BOOL; // 本次读标签是否成功 wReadCnt : DWORD; // 累计读取次数触摸屏上放一个当前托盘EPC显示框一个读取计数显示框一个通讯状态指示灯。操作工能直接看到当前托盘是什么车型维护人员也能直观看到通讯是否正常。最终验证我跑了三轮测试。第一轮同一个标签静止放在读头天线下方连续读100次统计成功率。第二轮把标签放在托盘上让托盘以实际生产速度通过读头看PLC能不能稳定读出EPC。第三轮随机抽20个不同标签每个读10次确认不是个别标签好用、换个标签就抓瞎。实测下来因为润滑脂、遮挡影响第二轮会偶尔丢读但通过状态机里的重发机制加上工位两侧各装一个读头交叉覆盖PLC最终读到的成功率能到99.8%以上完全满足了装配线的防错需求。5. 跑现场才遇到的坑粘包、断线重连与标签读不到的排查5.1 粘包问题最典型的TCP自由协议翻车点在实验室里跑单帧收发一切正常一到现场托盘连续过读头PLC解析就开始乱了。这就是TCP粘包在作怪。读写器极短时间内连续读到多张标签或者一张标签被连续触发两次产生的两个应答帧很可能在同一批TCP报文里发出PLC如果还是收到一次数据就当一帧解析就会把两帧混在一起解析出乱七八糟的EPC。我们的程序里做了接收缓冲和完整帧提取粘包没有造成大问题。但我见过不少项目偷懒直接拿本次接收到的数据当一帧解析结果一到连续过料场景就翻车。TCP自由协议应用里粘包拆包处理不是加分项是必做项。这一条放到任何工业设备用TCP传输自定义协议都成立。5.2 标签读取率下降金属干涉和射频功率的取舍现场还碰见一个时好时坏的问题同一套设备在实验室测试完全正常装到装配线工位后标签偶尔能读出来偶尔完全没反应。排查一圈最后定位到天线安装位置和旁边的金属立柱。读头天线装在工位侧边离一根金属立柱只有150mm托盘经过时天线发出的射频信号在金属面上反射形成驻波场强出现不均匀的盲区标签到了盲区里就完全读不到。处理办法是把天线安装支架往外移让天线边缘与最近金属面的距离拉开到300mm以上同时调整天线角度避免正对金属。此外还有一个容易被忽略的点很多人以为读取距离不够就把功率调到最大但在近距离金属环境下功率过大反而会让多径反射互相抵消。正确做法是把功率从低往高逐级调同时观察RSSI变化找到一个现场最优值而不是一味加大功率。5.3 断线重连机制PLC不能傻等自由协议通信里读写器随时可能因为断电、网线松动、交换机重启而掉线。如果PLC程序里只有一个连接成功后一直发送接收的流程一旦掉线Socket功能块会卡在那里等程序永远等下去。所以断线重连不是可选项是必须项。我这边PLC的断线重连逻辑是在S_WAIT_RESP状态启动一个500ms看门狗定时器超时没收到完整应答重发次数加1连续重发3次仍失败就认为TCP连接已经断开主动调用SocketClose关闭句柄清空接收缓冲状态转到S_RECONNECT延时2秒后重新执行SocketConnect。这样读写器恢复供电后最多2到3秒PLC就能自动恢复连接不需要人工重启也不需要按复位按钮。这套机制运行半年里救了好几次现场车间偶尔有电柜开关跳闸恢复供电后系统自己把通讯拉起来了操作工甚至都没注意到发生过断电。5.4 数据时好时坏的排查顺序最后把这种时好时坏问题的排查顺序总结一下。这个顺序是按实际经验排的照着走能最快缩小范围。第一步先用电脑连读写器发命令看电脑上读标签是不是完全正常。如果电脑上也是时好时坏问题基本在射频侧比如天线的位置、标签质量、现场干扰这时候改PLC程序没有任何意义。第二步如果电脑上正常PLC上不正常开Wireshark抓包看PLC发出命令后读写器到底有没有回包。有回包但解析失败把回包字节贴到CRC计算器里验证确认CRC算法和校验范围是否和读写器固件约定一致。第三步确认CRC没问题后检查报文里的长度字段。长度是单字节还是双字节、高字节在前还是低字节在前不同设备习惯不同很多能解析但永远错位的问题就出在这个字段上。第四步检查接收缓冲的完整帧提取逻辑。连续运行时特别要留意是否出现粘包后把两帧混成一场的情况这属于代码逻辑层面的问题通过单步跟踪能查出来。第五步查现场干扰。把天线附近的大功率电缆、变频器出线、伺服电机动力线整理走线必要时换屏蔽双绞线和SMA屏蔽馈线并确认接地没有形成地环路。按这个顺序排查半小时内能定位九成以上的自由协议通信问题。整个过程中最忌讳的是问题一出现就先怀疑PLC程序反复改代码却不抓包最后发现是网线头松了或者IP网段不一致白白浪费几个小时。整套方案讲到这里基本完整了。这套CK-LR08-E00读写器汇川AM401以太网TCP/IP自由协议的组合在我手上已经稳定运行半年多中间除了偶发断线重连和一次网线插头松动几乎没出过问题。如果让我给一句总结性的建议那就是动手写PLC程序之前先把报文格式和CRC校验在电脑端验证清楚联调会顺利得多通信程序里连接管理、超时重发、断线重连三件事一定要做成状态机不要用一路到底的线性逻辑。希望这篇实例能帮你少踩几个坑。