vlambda博客
学习文章列表

图解车载以太网 TCP 协议

点击蓝字 关注汽车以太网







图解车载以太网 TCP 协议

图解车载以太网 TCP 协议

“ 无论在互联网领域还是汽车以太网领域,TCP/IP 协议族中传输层的传输控制协议(Transmission Control Protocol,TCP)都有举足轻重的作用和大量的应用场景。TCP 是一种面向连接的、可靠的、基于字节流的通信协议,最初由 IETF RFC 793 定义,后续在 RFC 1122、RFC 2581 等文档中都进行了修订和补充。


不同于另一个同样位于传输层的用户数据报协议(User Datagram Protocol,UDP),TCP 的工作原理和交互机制要复杂很多,比如我们熟知的三次握手、四次挥手、发送确认以及状态机跳转等。本文把这些复杂的工作机制以图示的形式展示出来(个人认为图片的美观程度是全网最好的,些许强迫症,花了不少时间画的),希望能够帮助大家更好的理解 TCP 协议。


图解车载以太网 TCP 协议

全网最好看的

TCP 状态机、三次握手、四次挥手

图解车载以太网 TCP 协议

文中提到的 SYN 报文、FIN 报文或 ACK 报文指的是对应标志位置 1 的 TCP 数据段。



01

TCP 报头

开篇先送大家一个好看的 TCP 报头

图解车载以太网 TCP 协议

TCP 报头(遵循 RFC 793)示意图


02

TCP 状态机
图解车载以太网 TCP 协议

TCP 状态机示意图


03

TCP 三次握手建立连接
图解车载以太网 TCP 协议

TCP 三次握手建立连接示意图

上图为 TCP 三次握手的示意图,三次握手其实是通过三条 TCP 报文来建立连接的过程。主动打开连接的一端为 Client(图中的 ECU A),被动打开连接的一端为 Server(图中的 ECU B),这里的 Active OPEN 表示主动打开并发送 SYN 报文,相当于调用了 connect () 函数;Passive OPEN 表示被动打开并进入监听状态,相当于调用了 listen () 函数。


04

TCP 同时打开,建立连接
图解车载以太网 TCP 协议

TCP 同时打开并建立连接示意图

TCP 同时打开是一个特殊的情况,两端均想主动发起并建立连接,会同时发送 SYN 报文,在自己的 SYN 报文被对端确认之前,会先收到了对端请求建立连接而发送 SYN 报文,这时两端只需回复 SYN+ACK 报文,即可建立连接。


05

TCP 数据传输
图解车载以太网 TCP 协议

TCP 数据传输示意图

TCP 之所以可靠,除了建立连接、释放连接之外,还有数据确认、数据重传等工作机制,TCP 会给所要传输数据的每一个字节进行编号,也就是数据的序列号。数据传输完成后,对端会回复 ACK 报文进行确认,当一直未收到确认报文时,TCP 会启动重传机制,以保障了数据传输的可靠性。上图为数据传输和确认的示意图,图中的 SEQ 和 ACK 分别表示 TCP 报头中的序列号(Sequence Number)和确认号 (Acknowledgement number)。ECU A 和 ECU B 已经经过三次握手进入了 ESTABLISHED 状态,开始进行数据的收发,为了更好的介绍,我们假设 ECU A 当前传输数据的 SEQ = 1,ECU B 当前传输数据的 SEQ = 11,实际上,真实的 TCP 在建立连接时,为了防止网络攻击等情况,初始序列号 (Initial Sequence Numbers,ISN) 会是一个随机选择的很奇怪的数字。

 

自己发送的 TCP 报文的 SEQ 是和上一条接收到的对端发来的 TCP 报文的 ACK 相关联的,图中同样颜色的即为相关联的数字。ECU A 发送数据的第一个字节 SEQ = 1,所传输数据长度为 100 字节,也就是说 ECU A 现在要传输序列号 1 到 序列号 100 这 100 个字节的数据。如果数据被正确接收,ECU B 会回复 ACK 报文,报文中的 ACK = 101,表示 101 序列号之前的所有数据都已被我正确接收。这就是简单的发送和确认机制,图中我还举了一个例子,大家可以自己计算下。


06

TCP 四次挥手释放连接

TCP 四次挥手释放连接示意图

TCP 四次挥手是当数据传输完成后,两端想释放连接时,通过四条报文的交互进行连接关闭的过程。想主动关闭连接的一端(ECU A)会调用 close()函数(或者 shutdown()函数,因为不是专业码农,具体的区别就不多介绍了,免得说错),进而发出 FIN 报文,接收端(ECU B)收到对端的 FIN 报文后,会回复 ACK 报文进行确认。这时 ECU B 会询问自己的上层应用,是否还是数据要发送、是否需要关闭连接。如果还有数据发送,这时数据还是可以从 ECU B 发送至 ECU A 的(途中绿色 “ 数据传输 ” 箭头)。当所有数据均传输完成后,ECU B 也会调用 close()函数,发送 FIN 报文。四条报文传输完,被动关闭的一端会直接跳转至 CLOSE 状态,但主动关闭的一端会进入 TIME-WAIT 状态,在等待两个 MSL (Maximum Segment Lifetime,此值可配置,通常默认为 60 秒) 超时之后才会跳转至 CLOSE 状态,至此,四次挥手结束,连接关闭。等待 2 * MSL 是为了防止最后一条 ACK 未被 ECU B 正确接收,等待 ECU B 进行 FIN 报文重传的时间 。


07

TCP 同时关闭,释放连接

TCP 同时关闭并释放连接示意图

TCP 同时关闭和同时打开类似,两端同时关闭连接,同时调用 close()函数时会出现这种情况。这里会多一个四次挥手时不会出现的状态:CLOSING,当自己发出的 FIN+ACK 报文在未被对端确认就收到了对端请求关闭连接的 FIN+ACK 报文时,会直接回复 ACK 并跳转至 CLOSING 状态,直到收到了对端确认自己 FIN 报文的 ACK后 ,才会进入TIME-WAIT 状态,进而等待超时关闭连接。



今天就先介绍这么多

王师傅以后会和大家分享更多

车载以太网小知识

在以太网通信中,TCP 是一个非常基础的协议

欢迎大家留言讨论