☰
智能相机与PLC的Modbus TCP字符串传输与寄存器映射
2026/11/2 21:49:34 网站建设 项目流程

产线上视觉工位跑完一次检测,判定结果、缺陷代码、批次号这些信息还在智能相机里,PLC 那头却只拿到一个 OK/NG 的开关量——这是很多人第一次把机器视觉和控制器对接时最先撞上的墙。标题里说的这件事,核心就是把智能相机内部的一段字符串,通过 Modbus TCP 这条开放总线搬到 PLC 的寄存器区,让 PLC 读到“划伤-A03-20240511”这样的具体内容,而不是只有一个 0 或 1。设备型号我就不点名了,一说品牌容易被当成软广,反正通讯这一层的套路是完全一样的:一端组包发送,一端拆包还原,中间隔着一层字节序和地址偏移。这篇内容面向三类人——刚接手视觉工位、需要自己配通讯的电气调试,写 PLC 逻辑但没搞过字符串传输的程序员,以及想把这条链路吃透、以后换设备也能照搬的自动化从业者。整篇按“思路—参数—发送端—接收端—排查”的顺序展开,能直接抄的部分我会写清楚。

1. 通讯链路到底怎么搭:先把角色和数据流想清楚

1.1 谁当主站谁当从站,决定了后面所有配置

Modbus 是典型的主从结构,一条链路上只能有一个主站发问,从站老老实实应答。放到这条链路上有两条路可选:一条是 PLC 做客户端(主站),周期性去读相机的寄存器;另一条是相机做客户端,检测完成时主动往 PLC 的寄存器里写。很多人默认选了第一条,因为“PLC 是大脑”这个直觉太强,但实际跑下来,第二种更省事。

原因不复杂。轮询模式下,PLC 得按固定周期一直问“你有新数据吗”,相机每次都得应答一次,网络上的报文量跟产线节拍完全脱钩,节拍快的时候你嫌轮询太慢,节拍慢的时候又白刷一堆空包。更麻烦的是时序:相机刚写完结果,PLC 的轮询周期刚好错过去,那一次检测的数据就得等下一轮,碰上高速工位就是实打实的漏检。

反过来让相机主动写,逻辑就变成事件驱动——检测一结束,相机立刻组包、建立(或复用)连接、写寄存器、置标志位,整个动作在几十毫秒内完成。PLC 侧只需要盯着一个“序号”或者“数据有效”标志,变化了就取数。代价是相机侧要配客户端的连接参数,以及断线重连得自己处理。我的建议很明确:数据量小、实时性要求高、检测事件离散的场景,优先让相机做客户端主动写;如果是相机需要被多个上位系统同时访问,或者 PLC 侧本身就有成熟的轮询框架,那再考虑相机做从站。

这里还有一个容易忽略的点:智能相机当从站时,它能提供的寄存器区往往是有限且固定的,映射关系由相机固件决定,你只能读不能随意改结构。而当客户端主动写的时候,写什么、写哪里、写几个,全由你在相机侧的自由配置决定,灵活性完全不在一个量级。

1.2 为什么是 Modbus TCP 而不是别的现场总线

自动化圈子里的通讯方案多得是,Profinet、EtherNet/IP、EtherCAT 各有各的地盘,为什么这条链路偏偏选 Modbus TCP?我总结下来就三条现实理由,跟技术先进性没关系。

第一是落地成本。Modbus TCP 不需要专用的通讯卡、不需要组态描述文件、不需要在工程软件里导入设备描述,一根网线插上去,端口 502 通就是通。对于视觉这种“后加的、独立的、供应商可能换”的工位,这一点太重要了——你不可能为了一个相机去动整条产线的总线架构。

第二是调试可见性好。Modbus TCP 的报文结构简单到可以手工拼,用任何一台笔记本装个调试工具就能模拟主站发写指令,验证 PLC 侧收得对不对。这在现场排查时价值极高,你能把“相机的问题”和“PLC 的问题”干净地切开。相比之下,某些实时以太网协议出问题,你连从哪一层开始查都不知道。

第三是跨厂商的通用性。产线上设备品牌混用是常态,视觉一家、控制器一家、机器人又一家。Modbus TCP 几乎是所有设备都愿意支持的最小公约数,哪怕它只是个“能用”的级别。

注意:Modbus TCP 没有内置的认证和加密机制,它假设运行在一个受控的工业内网里。别把 502 端口暴露到办公网或者更外面,这不是技术偏好问题,是基本的安全习惯。

当然它也有明确的短板:没有数据类型的概念,所有东西都是 16 位寄存器;没有同步机制,写和读之间的一致性全靠应用层自己做握手;没有服务质量保证,网络抖动时丢了就是丢了,协议层不会帮你重传。这三点决定了你在应用层必须自己补一套“序号 + 标志位 + 超时”的机制,后面几节会详细讲。

1.3 字符串在寄存器里到底是什么样子

这是整件事最反直觉的地方,也是绝大多数乱码问题的根源。Modbus 的世界里没有“字符串”这个类型,只有寄存器。一个寄存器 16 位,装两个字节,你要传的字符串必须先变成字节序列,再按两个一组切块塞进寄存器。

举个具体的例子:字符串OK-A03,按 ASCII 编码是 6 个字节——4F 4B 2D 41 30 33。切块之后是三个寄存器:第一个装4F 4B,第二个装2D 41,第三个装30 33。听起来很直白,坑在后面:一个寄存器内部,两个字节谁在前谁在后?多个寄存器之间,顺序怎么排?这两件事在 Modbus 规范里其实是有明确定义的(寄存器内高字节在前,寄存器按地址递增传输),但PLC 内部存储数据的方式是另一回事,取决于它的 CPU 架构和编程环境的处理习惯。

于是就出现了经典现象:相机那边写的是OK,PLC 这边读出来是KO。不是谁错了,是两边对“一个 16 位数据里哪半边是高位”的理解没对齐。解决方式通常有三种:在相机侧做字节交换、在 PLC 侧做字节交换、或者干脆用“把字符串拆成单字节数组”的方式绕开寄存器语义。我个人的偏好是第三种,后面第 4 节会讲为什么。

还有一个必须提前决定的事:字符编码。纯英文和数字用 ASCII 最省事,一个字符一个字节,长度好算。但一旦涉及中文(比如缺陷描述写成“划伤”“气孔”),ASCII 就歇了,得用 UTF-8 或者 GBK。UTF-8 下一个汉字占 3 个字节,字节数不再等于字符数,长度计算、寄存器数量计算、PLC 侧的截断逻辑全都要跟着变。这事儿没有中间路线,只能一开始就定死,两边都用同一套编码,中途改一次等于全链路重做。

2. 参数与地址规划:动手前必须钉死的几件事

2.1 端口、单元标识与地址偏移的对齐

Modbus TCP 默认端口是 502,这个基本没人改,但**单元标识符(Unit ID)**是个高频出错点。理论上在纯 TCP 环境里,单元的区分靠 IP 地址就够了,Unit ID 字段意义不大,很多设备干脆固定填 1 或者 255。可一旦两侧的默认值不一样,有的设备就会默默丢包,表现成“连接建立成功但读写无响应”,特别迷惑。

我的做法是:先在相机侧的连接配置里找到 Unit ID 这一项,记下它的值,然后去 PLC 从站配置里核对,两边必须一致。如果 PLC 侧支持配置多个单元号,那就更要注意,一个单元号对应一块独立的寄存器区,写到别的单元号上去,数据不会报错,但就是读不到。

比 Unit ID 更隐蔽的是地址基准差异。Modbus 的寄存器地址在不同工具里有三种常见写法:协议地址(从 0 开始)、数据模型地址(从 1 开始)、以及带功能码前缀的写法(比如 4xxxx)。相机侧填的“起始地址 100”,在 PLC 侧可能是%MW100,也可能是%MW101,取决于中间有没有做过一次偏移。

判断方法很土但很有效:先写一个已知值到起始地址,然后在 PLC 在线监视里逐个看哪个寄存器变成了这个值。别猜,别照着别的项目的配置文件抄,一次实测比看十页文档管用。我见过一个项目因为地址差了 1,调试组三个人查了一整天,最后发现是相机侧地址框的提示文字写的是“从 0 开始”,而实际固件按 1 开始算。

2.2 寄存器数量怎么算才不踩坑

字符串长度和寄存器数量的换算,公式很简单但要留余量。按 ASCII 算,N 个字符占 N 个字节,需要ceil(N/2)个寄存器;按 UTF-8 算,先算出实际字节数再除以 2 向上取整。麻烦的是字符串长度是不固定的,缺陷描述有时三个字,有时十五个字。

这里有三种常见策略,各有取舍:

策略做法优点缺点
定长填充固定分配 16 个寄存器,不足补 0结构固定,PLC 侧好处理浪费寄存器,超长会被截断
长度字段 + 变长单独一个寄存器存字节数,后面跟数据节省空间,长度明确PLC 侧要多一步解析
结束符数据末尾补\0或\r\n实现简单数据本身含结束符时出问题

我一般选“长度字段 + 定长分配”的组合:分配固定的 32 个寄存器(64 字节)作为数据区,前面单独用一个寄存器记录本次实际用了多少字节。这样既不用在数据里找结束符(省掉一堆边界判断),又不会因为数据超长而悄悄截断——超长我直接报错,让调试的人知道配置不对,而不是让产线跑着跑着少了一段关键信息。

提示:寄存器数量一定要按“最坏情况”算,也就是最长的缺陷描述 + 最长的批次号 + 最长的时间戳,全部拼起来之后的字节数。别按平均值算,现场一定会出现你没想到的长字符串。

另外提醒一句,很多 PLC 的 Modbus 从站有单次读写寄存器数量的上限,常见是 120 个或者 125 个。如果你的数据区超过这个数,一次写不完,得拆成多帧。这时候就必须引入序号机制,否则 PLC 分不清哪几帧是同一批数据。

2.3 一套可以直接抄的寄存器映射表

规划寄存器区的时候,别把所有空间都给字符串,控制字和数据要分区放。我用的这套结构在好几个项目上跑过,直接抄没问题:

偏移数量类型用途
+01控制序号(每次发送自增,回绕 0-65535)
+11状态位 0:数据有效;位 1:PLC 已取走;位 2:发送方报错
+21数据字符串实际字节数
+31数据结果码(0=OK,1=NG,2=复检)
+428数据字符串数据区,56 字节
+3216预留扩展用,比如时间戳、工位号

留 16 个寄存器的预留区是我吃过亏之后养成的习惯。第一次做的时候把空间算得刚刚好,结果客户临时要求加一个“相机编号”字段,整个地址表得重排,PLC 侧所有引用地址的代码全改一遍。现在我至少留 20% 的空位,宁可浪费也不重排。

分区的另一个好处是控制字和数据分离。把序号、标志位放在最前面,PLC 可以用一次读多个寄存器的操作把控制区和数据区一起读回来,不用发两次请求。虽然 Modbus TCP 的请求开销不大,但读两次就意味着两次数据可能不同步——第一次读到序号变了,第二次读数据时相机又更新了,你拿到的就是半新半旧的组合。一次读全,永远是最稳的。

3. 相机侧实现:事件触发、组包与发送

3.1 把检测结果拼成一段可传的字节流

相机侧要做的第一件事不是配通讯,是定义清楚要传什么。我见过太多项目在这一步图省事,直接把整个结果结构序列化扔过去,结果 PLC 侧解析逻辑写了三百行,后期谁都不敢动。

务实的做法是把信息压到最小必要集。以视觉检测为例,真正对下游有用的通常就四项:判定结果(OK/NG)、缺陷代码(一个短标识,比如A03)、可选的测量值、以及一个能追溯到具体检测的序号。批次号、工位号这种不变的信息,没必要每次传,上电时传一次就行。

拼包的时候有几个顺序问题要注意。先放定长字段,再放变长字段,这样解析端可以按固定偏移直接取值,不用先算长度再算偏移。比如结果码 1 个字节、序号 2 个字节、然后是长度可变的描述字符串——解析的时候前三个字节的位置永远是固定的,逻辑简单很多。

如果相机侧的配置界面支持“变量到寄存器的映射”,注意它映射的是变量的原始二进制形式,不是你眼睛看到的字符。一个整数变量300,映射到寄存器是0x012C,不是字符3、0、0。想传字符300,得先把它转成字符串再映射。这个区别在配置时很容易搞混,尤其是界面上两种映射长得差不多的时候。

3.2 字节序与填充:最容易翻车的两个细节

字节序这事儿,前面提了个头,这里展开说。一个 16 位寄存器在 Modbus 报文里是按“高字节先发”的顺序传输的。相机把字符串AB(41 42)塞进寄存器,如果它按“第一个字符放高字节”处理,寄存器值就是0x4142,报文里发出去是41 42,PLC 收到后如果按“低字节在前”解读,就变成0x4241,显示成BA。

解决路径有两条。第一条是找到相机侧的“字节序”或者“字序”选项,试四种组合(大端/小端 × 字内交换/字间交换),看哪种能让 PLC 读出正确字符。这个方法很快,但属于试错,换个型号又得重来。

第二条是从设计上绕开这个问题:不让相机把两个字符塞进一个寄存器,而是每个寄存器只放一个字符的低字节,高字节固定填 0。这样不管字节序怎么折腾,PLC 侧读出来的每个寄存器都是0x00XX,取低字节就是字符,永远不会错。代价是寄存器用量翻倍,56 字节的数据区只能放 28 个字符。

我现在的默认选择是第二条路,除非字符数特别紧张。原因很实在:字节序问题在现场表现为“时好时坏”的概率很高(有些字符交换后还是合法字符,看起来像正常数据),排查成本远高于多占几个寄存器。

填充的问题同样烦人。定长分配的数据区,如果本次字符串比上次短,没覆盖到的寄存器还留着上一次的旧值。PLC 侧如果按“读到 0x0000 为止”来判断结尾,就会把上次的残留数据拼进来,出现OK-A03气孔这种诡异结果。解决办法是每次发送前把整个数据区清 0,或者严格按长度字段截取。我两个都做,双保险。

3.3 触发、握手与异常重试

相机侧的触发逻辑要跟检测流程绑定,一般是检测完成后的事件回调。这里有个时序细节:必须等所有结果变量都写完再触发发送,不能检测一结束就发。视觉系统的结果写入往往是多步的,判定先出,测量值后出,如果发送动作跟判定在同一步,你发出去的测量值可能是上一次的。

握手我用的是一套很土的机制,但可靠性经得起验证:

  1. 相机把数据写进数据区;
  2. 相机把状态寄存器的“数据有效”位置 1,同时序号加 1;
  3. PLC 检测到序号变化,读走数据,把“PLC 已取走”置 1;
  4. 相机看到“PLC 已取走”置 1,清掉自己的“数据有效”,并把“PLC 已取走”清 0,完成一轮。

这套握手的价值在于双方都知道对方处理到哪一步了。如果 PLC 因为某种原因没取走(比如扫描周期被长任务卡住),相机能通过超时发现,可以重发或者报警,而不是傻等着。

超时设多长?经验值是正常握手耗时的 3 到 5 倍。如果正常情况 50 毫秒完成一轮,超时设 200 到 250 毫秒。设太短会误报,设太长等于没设——产线节拍才 500 毫秒,你超时设 5 秒,等发现的时候已经漏了好几个工件了。

至于连接管理,强烈建议用长连接。每次发送都新建 TCP 连接,握手三次、慢启动、然后发几十个字节就关,开销占比高得离谱,而且频繁建连在某些设备上会触发连接数限制。长连接配一个心跳(比如每 2 秒写一次序号不变的空包,或者读一次状态寄存器),能及时发现链路断开。断线之后的重连我一般设 1 秒间隔、无限重试,同时在 PLC 侧用“心跳计数不变化超过 N 秒”来报警。

4. PLC 侧接收:还原字符串并交给业务逻辑

4.1 寄存器到字节数组的搬运

PLC 侧的第一件事是把寄存器区搬到一个字节数组里。为什么不用字符串类型直接接?因为不同控制器的字符串类型内部结构不一样,有的前面带长度字节和最大长度字节,有的是纯字符数组,直接往字符串变量上映射,很容易出现“前面多两个乱码字符”这种现象。

稳妥做法是自己维护一个字节数组,长度等于数据区字节数,然后按顺序把每个寄存器拆成高低两个字节填进去。用结构化文本写大概是这样(不同平台的语法细节会有差异,逻辑是通用的):

// 检测序号变化 IF wSeq <> wSeqLast THEN wSeqLast := wSeq; uiByteLen := wByteLen; // 长度合法性检查,防止越界 IF uiByteLen > 64 THEN uiByteLen := 64; xLenError := TRUE; END_IF // 寄存器拆字节,高字节在前 FOR i := 0 TO 27 DO abBuf[2 * i] := BYTE(wData[i] / 256); abBuf[2 * i + 1] := BYTE(wData[i] MOD 256); END_FOR xDataReady := TRUE; END_IF

这段代码里有两个细节值得说。第一个是长度检查必须做,而且要在搬数据之前做。相机侧万一配错了,发过来一个 200 的长度值,你不检查就往数组里写,轻则数据错乱,重则触发访问越界报错,整个控制器停机。第二个是BYTE(wData[i] / 256)这种写法在不同平台上等价于取高字节,但有的平台需要显式做移位,写之前确认一下目标平台的类型转换规则。

搬完之后,字节数组里的内容就是相机原始字节流,接下来才轮到编码处理。

4.2 字符编码转换与长度截断

纯 ASCII 的情况最简单,字节数组里的每个字节就是一个字符,按长度截取前 N 个,赋给字符串变量就行。需要注意的是赋值时的长度限制,目标字符串变量声明成STRING[32],你塞 40 个字节进去,超出部分会被截掉,但不同平台截断的行为不一样,有的是静默截断,有的会报错。安全做法是在赋值前自己按目标变量容量截一次,心里有数。

UTF-8 的情况复杂一些。UTF-8 是变长编码,一个汉字 3 个字节,直接按字节截断可能把某个汉字切成两半,产生乱码。正确做法是按字符边界截断:从前往后扫描,遇到0xxxxxxx开头的字节算一个字符(1 字节),遇到110xxxxx算两个字节的字符,1110xxxx算三个字节,如果剩余字节不够一个完整字符,就停在那个位置。

很多 PLC 平台没有内置的 UTF-8 解码函数,得自己写。写法不复杂,但边界条件容易出错,建议先在 PC 上用脚本验证一遍逻辑,再往 PLC 里搬。我在一个项目上因为少判断了一种起始字节模式,整整两天没找出来为什么某些汉字会变成问号。

还有一种偷懒但有效的方案:中文统一用 GBK 编码。GBK 是双字节定长(大部分情况),一个汉字正好 2 字节,跟一个寄存器完美对齐,字节序问题都省了一半。代价是跨系统兼容性差一点,如果下游还要往数据库或者 MES 传,得做一次转码。选哪个看你的下游环境,没有绝对的对错。

截断之后还有一步:去掉尾部的填充字节。如果相机用的是“不足补 0”的策略,字符串末尾会带一串\0,直接显示出来就是一串空白。按长度字段截取能避免这个问题,如果没长度字段,就得从后往前扫,把0x00和0x20都去掉——注意别把字符串内部合法的空格也去掉,所以从后往前扫、遇到第一个非空白就停。

4.3 握手信号与消费完成后的清理

PLC 取完数据、转成字符串之后,得回写握手信号,告诉相机“我拿到了”。这一步的时机很关键,必须在数据真正被业务逻辑消费之后,而不是刚搬进数组就回。

我踩过的坑是这样的:PLC 一检测到序号变化就回写“已取走”,然后把数据放在缓冲区里等后续逻辑处理。结果后续逻辑因为某个条件没满足,走了另一条分支,缓冲区没被清理,下一轮数据来了直接覆盖,那一条检测记录就丢了。因为握手信号已经回了,相机以为处理完了,也不会重发。

改法很简单:握手信号在业务逻辑确认使用完数据之后再置位,中间加一个“处理中”的中间状态。如果处理超时(比如 500 毫秒还没完成),就报警而不是继续等。这样任何一个环节卡住,都能被看见。

还有一点:数据消费完之后,缓冲区要主动清零,而不是等着被下次数据覆盖。原因跟前面说的一样——万一某次发送的长度字段异常,没有覆盖全部区域,残留的旧数据会污染后续解析。清零这个动作成本几乎为零,但能挡掉一类很难复现的问题。

5. 联调排查实录:这些坑我基本都踩过

5.1 故障速查表

现场出问题时,先对着这张表过一遍,能解决八成情况:

现象最可能的原因快速验证方法
连接建立成功但读不到数据Unit ID 不一致两侧配置里核对单元号
数据写进去了但地址不对地址基准差 1(0 起始 vs 1 起始)写已知值,在线监视逐个寄存器看
字符顺序颠倒(AB 变 BA)寄存器内字节序不一致相机侧或 PLC 侧交换高低字节
字符串尾部带乱码数据区未清零,残留旧值发送前整体清 0 验证
只有前半段正确寄存器数量算少或长度字段错误核对字节数与寄存器数换算
偶发丢数据无握手机制,数据被覆盖加序号 + 标志位
中文显示成问号编码不一致(ASCII/UTF-8/GBK)统一编码后重测
通讯时通时断网络抖动、IP 冲突、连接数超限抓包看是否有重传或 RST
相机侧发送报超时PLC 从站未开启或端口被占用调试工具直连 PLC 端口测试

5.2 分层排查法与抓包看什么

通讯问题最忌讳的是“从中间猜”。我的习惯是从两头往中间夹:先用一个 Modbus 调试工具模拟主站,直接往 PLC 写一段固定字符串,验证 PLC 侧解析逻辑对不对;再用同一个工具模拟从站,让相机往它写,验证相机侧的组包对不对。两头都通了,问题必然在中间的链路上——网线、交换机、IP 配置、防火墙。

抓包这步很多人跳过,觉得麻烦,但它能省下大量时间。看什么?主要看三样:

第一,看请求有没有发出去。如果相机侧显示“已发送”但抓包一个包都没有,那问题在相机侧的连接状态,根本没到网络上。

第二,看响应码。Modbus 的异常响应是功能码加0x80,后面跟一个异常码。异常码0x02是地址非法,0x03是数据值非法,0x04是从站设备故障。看到异常响应,说明报文到了 PLC,是 PLC 拒绝了这个请求,问题在地址或数量上。

第三,看字节内容。抓包工具能把报文的十六进制展开,你直接对着看:MBAP 头之后是功能码,再往后是起始地址和寄存器数量,再往后是字节数和数据。把数据段和你期望的字符串对一下,一眼就能看出是字节序错了还是根本没写对。

提示:抓包时注意区分“重传”和“新请求”。TCP 重传说明网络层有问题,可能是线缆、接口或者交换机端口;新请求但响应异常,说明应用层配置有问题。这两类问题的排查方向完全不同。

5.3 几条不太写在手册里的经验

第一条,先跑通再优化。我见过有人一上手就设计了一套带 CRC、带分包、带重传确认的复杂协议,结果调了三天连不上。正确顺序是先让一个固定字符串能完整传过去,再往上加序号、加长度、加握手、加异常处理。每加一层都验证一遍,出问题能立刻定位到刚加的那一层。

第二条,把调试信息留在寄存器里。在数据区后面留几个寄存器,专门放“发送次数”“最后错误码”“最后成功时间戳”。这些东西平时没人看,出问题的时候是救命的。相机侧发送失败的原因往往在相机内部日志里写得含糊,但你自己记的错误码能直接指到具体环节。

第三条,别信“默认值”。相机侧和 PLC 侧的通讯参数,凡是带默认值的选项,都要显式确认一遍。端口、Unit ID、字节序、超时、重连次数——这些默认值在两个厂商的产品上几乎不可能完全一致,而它们不一致时的表现往往是“看起来在工作,但数据偶尔不对”,这种问题最难查。

第四条,节拍和超时要一起算。通讯超时不能拍脑袋定,得按产线节拍倒推。假设工位节拍 800 毫秒,那从检测完成到 PLC 拿到数据,整个链路必须在这个时间内完成,留给通讯的预算可能只有 100 毫秒。超时设 200 毫秒就已经意味着这一件要漏了。算出预算再定参数,别等上线了发现节拍跟不上再回头改。

第五条,换设备的时候先看“它把字符串当什么”。不同厂商对“发送字符串”这个功能的理解差别很大:有的让你直接填字符串,内部自动分包;有的要求你先转成字节数组再按寄存器映射;还有的把字符串当成一个整体对象,映射出来的寄存器结构里带长度头和结束符。换设备的时候,第一步永远是搞清楚它的字符串在寄存器里长什么样,而不是照搬上一套配置。

最后分享一个我一直在用的小习惯:每接一个新设备,先花二十分钟做一次“最小闭环验证”——相机发一个固定的 8 字符字符串,PLC 收到后原样回写一个应答,两边都对得上,再开始接真实业务数据。这二十分钟看起来是浪费,但它把字节序、地址偏移、编码、握手这四类问题一次性排除掉了,后面调试业务逻辑的时候,你至少知道通讯层是干净的。我在最近几个项目上都保持这个流程,实际算下来,整体调试时间反而比上来就接业务数据要短。

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

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

立即咨询