上次在论坛上看到一篇好文章,出自西门子专家天团冯学卫专家关于“如何将TCP理论知识应用到实际的项目,并解决实际项目的问题”。跟大家分享一下,建议关注收藏,需要的时候可以借鉴一下。
这个案例涉及到了TCP协议的工作原理,我们知道应用层的数据需要借助TCP传输层协议传输时,需要在通信的伙伴之间建立TCP的连接,这也是经常被称为“三次握手”,如下图所示:
三次握手的过程中,标志位和序列号按如下图方式被设置:
第一次握手:客户端发送标志位SYN=1, 发送序列号seq =x(这里x是客户端操作系统初始化的一个序列号)包到服务器,并进入SYN_SENT状态,等待服务器确认;
第二次握手:服务器收到SYN包,并会确认客户的SYN 请求,
服务器会发送一个标志位SYN=1 和ACK=1,确认序列号 ack=x+1(x是刚从客户端中接收到的发送序列号,通过x+1服务器确认收到了客户端SYN请求包),发送序列号 seq=y(这里y是服务器操作系统初始化的一个序列号)包到客户端,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送标志位ACK=1,发送序列号seq=x+1(x+1对于客户端来说已经发送过1个SYN的包,所以此次的序列号需要在初始的序列号x的基础上再加上1),确认序列号ack=y+1(y是刚从服务器端接收到的发送序列号,通过y+1客户端确认收到了服务器发来的 SYN+ACK的包)。此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
可以看到握手时会在客户端和服务器之间传递一些TCP头信息,比如ACK标志、SYN标志以及挥手时的FIN标志等。
除了以上这些常见的标志头信息,还有另外一些标志头信息,比如推标志PSH、复位标志RST等。其中复位标志RST的作用就是“复位相应的TCP连接”。
导致“复位相应的TCP连接” 的其中一个原因是服务器端因为某种原因关闭了Connection,而客户端依然在读写数据,此时服务器会返回复位标志“RST”。
RST复位标志发送原因几种可能:
1. 被中间的防火墙设备拦截
2. 对方端口未打开
3. 全连接队列已满(超出了设备支持的TCP连接资源)
4. 设置 connect_timeout(应用设置了连接超时,sync 未完成时超时了,会发送rst终止连接。)
5. 非正常包(连接已经关闭,seq 不正确等)
6. TCP在建链时,发出SYN报文之后,60秒之内都没有收到对端的相应报文,会发送RST报文。
7. TCP报文在连续重传阈值次数之后,都没有收到对端相应报文时,会发送RST报文。
8. KeepAlive报文在连续发送5次之后,都没有收到对端的KeeAliveReply报文时,会发送RST报文。
回顾完理论知识,我们在看一下现场的网络拓扑结构如下图所示:
在华为的超融合网络中虚拟服务器中安装有MES系统和KEPServer OPC服务器。MES通过OPC的方式从KEPServer OPC 服务器读写数据,KEPServer OPC服务器通过自己集成的S7-300驱动程序经由路由的网络结构读写S7-1200和S7-1500中的数据(即KEPServer所在的虚拟主机在一个VLAN X子网,S7-1200和S7-1500在另一个VLAN Y子网)。KEPServer配置的驱动如下图所示:
现场出现的问题是PLC采用 S7-1500+CP1543-1的方案通信没问题,即KEPServer OPC服务器可以正常读写PLC中的数据;但PLC采用S7-1200集成口或S7-1200+CP243-1 或 S7-1500集成口的方案时,KEPServer OPC服务器不能正常读写PLC中的数据。
在现场已经排查出不是KEPServer OPC服务器的问题,在服务器所在的位置用TIA Portal 软件也无法在线连接到S7-1200。那现在只能怀疑超融合的网络可能有问题。为了验证,现场脱离了原有的超融合网络架构,用西门子SCALANCE XC208模拟超融合网络的路由网络架构。且IP子网设置与现场的超融合网络KEPServer OPC服务器所在虚拟主机相同的子网和相同的IP地址。模拟网络架构如下图:
采用上面模拟的超融合网络架构的结果是所有的PLC都可以正常与KEPServer OPC服务器通信(S7-1200集成口、S7-1200+CP243-1、S7-1500集成口或S7-1500+CP543-1的方案都正常通信)。
从测试的结果来看,不是PLC通信性能的问题,而是网络存在这一定的问题。为了找到问题的正真原因,我们在KEPServer OPC服务器所在的超融合网络的虚拟主机与S7-1200 PLC 上同时抓包分析(在PLC下载完程序启动的时候就开始抓包)。
在KEPServer OPC 服务器端抓取到的文件命名为:“04_CP_1200_Fault_2023_10_28_CaptureInSERVER.pcapng”
在S7-1200 PLC端抓取到的文件命名为:
“04_CP_1200_Fault_2023_10_28_CaptureInPLC.pcap”
KEPServer OPC 服务器所在的虚拟主机的IP地址“10.16.3.110“,子网掩码”255.255.255.0“ 网关地址”10.16.3.1“。
S7-1200 CP卡的IP地址为”10.18.61.8/23“,子网掩码”255.255.254.0“ 网关地址”10.18.60.1“。
通信的两个设备不在同一个IP子网中,需要通过华为超融合网络的路由器来实现数据的路由转发。从S7通信的角度看,此时KEPServer 为S7的客户端,S7-1200 PLC为S7服务器。我们对照着理论部分的TCP建立过程来看S7通信建立的TCP的建立过程。
先看在KEPServer S7客户端抓包文件,分析如下图:
再看再PLC S7服务器端的抓包文件,分析如下图:
问题就出现在TCP的三次握手的第三次,从KEPServer端看发出正常的ACK=1的确认包,而当通过网络转发给PLC的时候,该包被修改,除了原来ACK=1外又被修改RST=1,源发送者可没有发送RST=1。换句话说,PLC的三次握手的最后一次没有正常,所以PLC的TCP连接没有进入到TCP连接建立的状态,也就是所谓的TCP半连接状态。PLC的TCP既然没有完全建立成功,所以发送过来的任何的应用层请求连接都会被PLC发送RST=1的包。可以用下图来示意上面的连接过程:
对于客户端已经完成了三次握手,所以客户端的TCP状态机已经进入到了 “ESTABLISHED“状态;而对服务器端由于没有正确收到 ACK的报文,而是收到ACK和RST同时为1的包,所以服务器端的TCP状态机只是进入到了 ”SYN-RCVD“状态,没有进入到下一个状态 ”ESTABLISHED“。这是造成现场问题的正真原因。
我们再对比两端的三次握手的数据帧:
第一次握手的数据包对比:
我们发现端口号,发送序列号和确认序列号及TCP标志位都一致。
第二次握手的数据包对比:
我们发现端口号,发送序列号和确认序列号及TCP标志位也都一致。
第三次握手的数据包对比:
我们发现端口号,发送序列号和确认序列号一致,但TCP标志位发生了改变。
从这个案例可以看到理论知识的重要性,只有掌握了理论知识才能在现场解决所谓的疑难的问题,原因是你“有理有据“。
--老王的工控笔记
扫码关注了解更多
楼主最近还看过