为什么要说TCP 随着整车EE 架构的不断推进,对通讯的要求逐渐增加,数据的体量也在指数上升。开个玩笑定义一下以后的汽车可能是:“网线插在燃料上,带着沙发到处跑”
这里就不得不说到以太网。说到以太网又不得不说一下TCP/IP. 有的朋友会说,AP 里面聊的都是DDS, SOME/IP,DO/IP。为什么要聊TCP/IP , UDP呢。– 因为我们是基础软件。汽车在设计,开发,使用阶段,无论是系统工程师,还是软件工程师,都需要对其进行了解。
下面我们通过仿真软件(和实际的一样),来逐帧分析TCP/IP的握手与断开细节。
环境搭建
首先我们准备一台PC 和 一台服务器, 这里用简单的网线直连。
下面我们让电脑和服务器处于同一网段。 这里设置 电脑的静态IP: 192.168.1.2 服务器的静态IP:192.168.1.1
这里环境搭建完毕,下面我们使用PC 来通过访问web的方式来访问Server, 里面我们现在之分析 TCP 的报文,当然也要包括Http的应用层,这要针对TCP。我们设置一下。
到这里环境搭建完毕。开始跑起来。
方便观察,一下步骤皆为单步运行。
建立连接 首先我们让PC 以访问网页的方式去访问服务器的IP。
这里可以看出来,
PC端首先生成了一帧报文
准备发送出去的报文。下图是从七层架构的说明。这里只聊一下TCP层。可以看出来,TCP之后封装到IP,然后是链路层,最后就到了硬件。
报文解读:
-
PC 尝试与192.168.1.1 在port80上建立一个TCP 连接
-
连接状态为SYN_SENT
-
下面就是一些属性参数,可以自行查找。我们需要关注的是,第一帧PC 的SYN 标志位。
有了这个初步认识,我们从报文本身的角度去看一下如何封装。下图为PDU信息。
好,这里我们已经明白了PC准备的第一帧握手报文。下面我们把它发出去。
下面我们看一下Server 如何处理。
从七层结构开始说起。
左边是刚才Server收到的PC 报文。右边是Server准备回复的报文。
可以看出了除了属性参数之外,server端对SYN 做出了ACK。也就是说 server 对 PC 的连接请求有了回应,并且相对应的flag置位了。
从PDU 的角度也可以看出来。下面的PDU 可以和PC发送的PDU 进行对比。有一个flag 被置位。
仔细点的朋友可能会看出来PDU里面有个信息不正常。是sequence number为0. 这是因为仿真软件计数从零开始,实际的报文这里可能是个随机的数,其实也不是随机的数,是根据data package的长度,递增的数。这里知道即可。
好,我们继续前进。
PC收到了消息。我们看一下,收到并且是如何回复的。
这里可以看出来PC收到了server的ack信息之后,准备了一帧报文准备回复。
这里需要注意两个细节,
-
sequence number 增了1
-
对ACK进行了ACK‘
可以看一下封装的PDU。可以详细的看出 sequence number的位置,和flag的位置。
从server端可以监控到 来自PC的ack信息。
这里清楚的写着connection 已经建立。并且可以看出来。server端没有准备输出的报文。也就是说这时候Server端处于监听状态,监听来自PC的报文。
到这里位置握手环节结束,也就是下图,
数据传输
上面建立好了TCP 连接。
PC端开始进行数据传输,我们看一下数据传输的信息。
Sever端收到一帧来自PC的 PUSH报文。请求在1042port上。PUSH位置位,
TCP协议中的PUSH标志位是TCP首部中的一个标志位字段,它用于控制数据的传输方式。
当TCP报文中的PUSH标志位被设置为1时,它表示发送方的数据应该立即传输给接收方,而不需要等待缓冲区填满或者等待计时器超时。这个标志告诉接收方应立即传递数据给应用层,以便实时处理或者显示。
这个机制在需要实时数据传输的应用中非常有用,例如即时通信应用或者实时语音/视频传输。通过设置PUSH标志位,发送方可以尽快将数据传送给接收方,而不需要等待额外的延迟。
需要注意的是,PUSH标志位只是一个建议,接收方并不一定非要立即进行数据传递。这取决于具体的实现和网络状况。
简单一句话,PC发送数据给server了。
我们看看server如何回复。
收到PC的请求之后,这里ACK进行置位,注意后面跟着471个长度的数据,这里指的是应用层的数据Http.
像我们做汽车软件的,这里的数据可能来自some/ip 等等来自应用层的数据。
看一下server回复的pdu 分布。注意一下箭头位置即可。
下面PC端收到了来自server的回复。也就是说 网页有响应了。
我们来看一下怎么回事。
上面的这个过程就是数据传输,如下图。
这里之后PC端没有了数据请求。就不需要连接了。PC端主动发起断开连接。
断开连接
PC端发送第一帧断开连接,这时候 发送FIN+ACK Server 端把TCP状态设置为CLOASE_WAIT
可以从PDU 里面的flag 看出。
下面server需要对断开请求做出回复。
回复的信息如下,状态设置为closing.
当然这时候PC 还需要进行ACK 反馈。
直到最后服务端进行最后的ack.
然后设置状态位close. 自此 TCP 断开连接。
上述就是断开的四次挥手环节,如下图。
总结一下
回顾整体报文,一共经过了以下几个来回的交互。 希望对大家有一点点帮助。