文章目录
- 一、TCP[!]
- 1.1、TCP协议报文格式
- 1.2、TCP十大机制
- 1.2.1、确认应答机制
- 1.2.2、超时重传机制
- 1.2.3、连接管理机制
- 1.2.3.1、三次握手[其流程至关重要,面试必考]
- 1.2.3.2.1、那为啥要建立连接??建立连接的意义是啥??
- 1.2.3.2、四次挥手
- 1.2.4、滑动窗口机制
- 1.2.5、流量控制机制
一、TCP[!]
1.1、TCP协议报文格式
TCP协议报文格式的表现形式1:
TCP协议报文格式的表现形式2:
1、源端口号、目的端口号:
端口号是传输层协议的一个重要部分,知道了端口号,才能进一步确认这个数据报应该交给哪个应用程序;所占字节也都是2个字节,TCP的端口号其使用规则与UDP的端口号一致。
2、32位序号、32位确认序号:
32位序号这个字段用来给普通报文使用,32位确认序号这个字段用来给确认应答报文使用的,确认应答:即数据报被正确传送,并且返回响应。
3、4位首部长度:
TCP的报头是 变长 的,4位(bit)首部长度表示的数据范围是 0 ~ 15,但是其实此处 0 ~ 15 的单位是字节 ,即 4字节 ~ 15*4 字节,才是真正的首部长度。因此 TCP 数据报的最大长度最短、固定时是20个字节,最长时是60个字节。故TCP能够传送的数据比只能够传送64KB的UDP协议要多得多。我们需要使用首部长度来判断,报头到哪里结束,而载荷部分从哪里是开始。
4、6位保留位:
保留位是设计TCP协议的团队,汲取了UDP64KB长度的教训,用来给未来TCP留下可以升级扩展的空间的一个字段。其实就类似我们电脑预留的接口、插槽一样。有的电脑是轻薄本,因此可能只能够插一个内存,但是有的电脑他的设计师设计电脑时预留了很多插槽,即使可能这些插槽用户也用不上,但是还是预留了,以防出现突发情况。相对的,这些电脑,价格也就会相对插槽少的电脑昂贵一些,虽然价格昂贵,但是也还是会有大部分的用户选择这类扩展性好的电脑。
保留位后面是6个标志位,分别是:UBG、ACK、PSH、RST、SYN、FIN,他们的具体含义后续会补充介绍。
5、16位窗口大小、16位校验和、16位紧急指针:
暂时不用了解。
6、选项:
选项部分,可以有,也可以没有;可以有一个选项,也可以有多个选项。最少是0个字节,最多可以是40个字节。
7、载荷数据:应用层数据报。
1.2、TCP十大机制
TCP特性:
1、有连接
2、可靠传输:可靠传输是由内核实现的,我们写代码时无法感知到。(TCP的可靠传输不代表安全传输)
3、面向字节流
4、全双工
那么TCP就围绕这4个特性,提供了一系列重要的 机制 ,让我们更深入的理解报头结构。
1.2.1、确认应答机制
确认应答机制,是保证 TCP “可靠性” 最核心的机制。
举个例子理解:
上述情况3其应答消息就出现了 “后发先至” 的情况。其实不止代码会发生这样的情况,现实生活中,这类情况比比皆是:
比如说:结婚时的接亲过程:接亲一般就是男方开婚车队伍到女方家。一般来说,接亲车队的车辆排列顺序都是有一定讲究的一般是新郎的车在最前头。但是,有可能在接亲路上遇到一些突发状况(比如过红绿灯时),导致新郎的车落在后头了,别的婚车在新郎前面了。
那对于传输在网络中的数据也是一样的,数据从主机A发出,到被主机B接收的这一过程中,数据在网络中走的路线有很多,同时每个节点(路由器/交换机)的繁忙程度不一,此时,这样的转发过程,就会存在差异,就和等红绿灯一样。
那怎么保证数据的可靠传输(数据的顺序性、数据的完整性、数据的正确性…)??可以 针对数据进行编号 解决该问题。
1.2.2、超时重传机制
针对丢包、传输失败的数据,进行重传。
如果发送方的数据丢了,正常超时重传就行;
如果是确认应答报文(ACK)丢了,有两种情况:
(1)、ack发送成功,但接收方不回复,无视你的消息,发送方也会进行重传,因为发送方得不到回复,就会认为数据丢包了。
(2)、ack发送失败,你收不到回复。针对2这种情况,正常重传即可;针对1这种情况,会导致接收方收到重复内容的消息,这不太好。因此TCP针对接收方丢失ACK而受到重复的消息这种情况,他会根据消息的序号来进行 去重 ,即如果接收方已经收了一个序号为 1001 的数据,没多久又收到 1001 序号的数据,此时 TCP 就会将序号相同的消息进行去重。
那么超时时间如何确定 ??一般系统中有一个配置项,描述了超时的时间阈值。例如:第一次丢包出现后,发送方就会在达到超时时间阈值之后,进行重传;如果重传的数据仍然无响应,还会继续超时重传,第二次的超时时间一般要比第一次更长。超时的时间并非是均等的,而是逐渐变大的。因为假设单个数据报丢包的概率为10%,那么第一次丢包的概率是0.1,第二次丢包的概率是0.1 * 0.1 = 0.01,因此丢包的概率是逐渐减小的,所以第二次传输,大概可以顺利到达的,所以超时重传的时间是逐渐变大的。那如果第二次传输也没有到达,说明当前网络环境比较糟糕,那单个数据报丢包的概率可能非常大,甚至概率是100%的,断网了,都断网了,再怎么频繁的重传,也没用,所以把超时重传的频率降低一点(时间间隔长一点),至少可以节省主机的开销。
超时重传几次之后,仍然无法传输,就会尝试重置 TCP 连接(断开连接),如果还是连不上,此时就直接释放TCP连接(彻底放弃)。
那到底基础的重传间隔时间是多少?每次间隔增加多少??最多重传几次??不知道!没有具体的参数,因为不同的系统他们的时间都不一样,一旦给出了具体的参数,可能大家就会对此数值过度关注,甚至于对此数值死记硬背,没必要,我们需要关注的是超时重传此机制的本身策略,而不是这个数字。
典型的反例就是HashMap解决哈希冲突,是通过链表的方式,但如果链表太长了怎么办??需要把链表转成红黑树。那链表元素个数达到多少时,会转成红黑树呢?不知道,不好说!不同的哈希表的表现方式不同,只是 JDK1.8 标准库的 HashMap 是按照这个数字来设定的,如果是其他版本的 JDK 或者不是标准库实现 或者是 其他语言中的其他版本的实现,还是不是这个数字,不好说!
不变的是策略,可变的是参数。
1.2.3、连接管理机制
连接管理机制:描述的是TCP建立连接和断开连接的过程。
什么是连接?
(1)、物理上的连接:使用网线把两个电脑连上,这是 “物理上” 的连接。
(2)、逻辑上的连接:只要是网络通信,不管是用 TCP 还是 UDP 还是别的协议,物理上已经连接好了。逻辑上的连接就是:主机A与主机B建立连接,主机A的系统内核里,记录了一个数据结构,包含了和他连接的对方信息(IP、端口、使用的协议…);主机B的系统内核里,记录了一个数据结构,包含了和他连接的对方信息。
1.2.3.1、三次握手[其流程至关重要,面试必考]
三次握手只能是客户端先握,四次挥手既可以是客户端先挥,也可以是服务器先挥。[!]
TCP是通过三次握手完成建立连接的(即双方建立一个相互认同的关系)。
[!]
ack 标志位我们前面已经讲过了,ack = 1,表示当前是个应答报文,ack = 0,表示当前是个普通报文。syn 也是TCP报头6个标志位里的其中之一,syn = 1,说明这是一个同步报文段(即:尝试和对方建立连接);syn = 0,则反之。
1.2.3.2.1、那为啥要建立连接??建立连接的意义是啥??
1、投石问路。即:检查一下当前的网络情况是否是通畅的。就像地铁每天运营之前,都需要先空车跑一趟,来看看当前地铁线路是否畅通。
2、三次握手同时也是在检查通信双方的 发送能力 和 接收能力。
3、三次握手过程中,也在协商一些重要参数。
TCP 里面有很多参数需要协商。例如TCP的序号并非是从1开始的,通常都是建立连接的时候协商了一个数字。目的是保证两个连接的序号有差别,如果连接断开又快速重连,
接收方就可以区分当前收到的数据是当前连接的还是上个连接的。
TCP3次握手的详细流程图:(流程图上详细说明了TCP3次握手的两个比较重要的状态,当然还有别的状态,但就不一一列举了)
1.2.3.2、四次挥手
四次挥手用于断开连接,即双方取消相互认同关系。通信双方,各自向对方申请断开连接,再各自给对方回应。
那4次挥手能像3次握手那样合并吗??不一定能。为什么??
TCP4次挥手的详细流程图:(流程图上详细说明了TCP4次挥手的两个比较重要的状态,当然还有别的状态,但就不一一列举了)
ACK( acknowledge应答) 和 响应(response) 是否相同呢??
不相同。ACK只是告诉发送方,我收到数据了。而 响应 则是携带业务上的数据。
就像一些企业所用的软件:企业微信、钉钉、飞书、雨雀…当A给B发消息,网络没问题的话消息就会顺利传送到B处,那这个消息上就会出现 “已读” 两个字,这就是ACK,即系统内核收到请求就会立即返回的,不表示任何业务上的概念,只是单纯进行反馈而已。B收到消息后,回复的内容,就是响应,他表示了具体的业务数据,是由应用程序负责的,取决于代码怎么写。
1.2.4、滑动窗口机制
TCP通过 超时重传机制、确认应答机制、连接管理机制 来确保TCP协议的可靠传输。由于TCP协议是可靠传输,因此TCP的传输效率比UDP慢一些,但是 TCP 也在想方设法的提高自己的传输效率。即通过 滑动窗口机制。
上面我们讨论的是使用滑动窗口机制时是在正常的情况,如果在使用滑动窗口机制时,出现了 丢包(1、发送方传的数据丢了。2、接收方回复的ACK丢了) ,那该怎么办??
情况一:数据报抵达,但 ACK 丢了。
丢了就丢了,对于TCP的可靠传输没有任何影响,无需处理。这是因为,虽然丢了,但是只要后面发送的数据有ACK就足够了。
比如1001丢了,但是后面ACK 2001 成功了,此时就说明其实 1001 也已经 ACK 成功了。
就好比,有人问你,大学毕业了没,你回答说你已经硕士毕业了,这时候人家就明白了,原来你已经小学、初中、高中、大学都毕业了。
情况二:数据包丢包了。
在上述设定中,只是把丢失的数据进行了重传,没丢的包,无需重传,这种传输效率比较高,叫做 “快速重传”(快速重传是搭配 滑动窗口机制的 超时重传)。当传输数据很多时,批量传输,自然是遵守快速重传的方式,但如果传输的数据很少(就只有一条),此时仍然是按照超时重传的方式进行。只要是丢包重传的,都是 “超时重传”,快速重传算是超时重传的特殊情况。
1.2.5、流量控制机制
使用滑动窗口机制之后,TCP协议效率高不高,主要取决于窗口大小,窗口越大,效率越高;窗口越小,效率越小。假设窗口大小是无限大、无穷大,此时发送方就完全不需要等待ACK了,此时效率就和 UDP 协议是一样的了。但是发送方的窗口大小不能无限大,要考虑接收方的接受能力。因此TCP协议的 流量控制机制 出现了。