网络原理(13):TCP协议十大核心机制 -- 确认应答 & 超时重传
文章目录
- [网络原理(13):TCP协议十大核心机制 -- 确认应答 & 超时重传](#网络原理(13):TCP协议十大核心机制 -- 确认应答 & 超时重传)
- 观前提醒:
- [1. 确认应答](#1. 确认应答)
- [2. 超时重传](#2. 超时重传)
-
- [2.1 丢包](#2.1 丢包)
- [2.2 两种情况](#2.2 两种情况)
-
- [A --> B 发送的数据丢了](#A --> B 发送的数据丢了)
- [B --> A 返回的 ack 丢了,A没有接收到 ack](#B --> A 返回的 ack 丢了,A没有接收到 ack)
- 去重
- [3. 确认应答 & 超时重发 实现可靠传输](#3. 确认应答 & 超时重发 实现可靠传输)
- [4. 总结](#4. 总结)
观前提醒:
如果你是第一次点击这篇博客,需要你点击这篇博客的链接:
网络原理(12):传输层 -- TCP协议的报文格式 & 十大核心机制的博客目录
了解这篇博客的内容之后,再回来看这篇博客。
此处,我们讲到的 "TCP数据报的发送",例如:发送 ack(应答报文)
一定是要通过 IP协议封装(网络层),数据链路层封装,通过物理层转为光电信号,传输给对端,对端接收到光电信号,也要反着解析一遍(分用)。
关于封装和分用,可以看我的这篇博客:
Java网络初识(4):网络数据通信的基本流程 -- 封装
Java网络初识(5):网络数据通信的基本流程 -- 分用
1. 确认应答
这块内容很多需要介绍,大概有 4000字。
如果在这篇博客一起讲了,整体博客的字数就会达到 7500字。
为了减轻一篇博客的阅读量,我将 确认应答 机制的介绍,放在了这篇博客当中:
TCP核心机制:确认应答
推荐点击链接,看完 确认应答机制的博客,再回来看这篇博客。
2. 超时重传
TPC协议 ,具有 可靠传输 的特点。
上述讲到的第一个机制:确认应答
是实现 可靠传输 的一部分条件 。
确认应答 ,就是 发送方,发送数据给 接收方,接收方 返回应答报文,告诉发送方 ,接收方已经收到数据了。
但是,如果 接收方 ,没有返回响应报文呢?也就是,没有接收到数据呢?
数据出现丢失,这种情况,我们也叫做丢包 。
在这篇博客中:
Java网络编程(1):(使用 socket 进行网络编程前的预备知识)
我们第一次提到了丢包。
超时重传,就是针对丢包的情况,进行处理的。
2.1 丢包
什么情况下会发生丢包呢?
这里例举两种情况:
- 自然现象 ,导致磁场发生变化
很经典的一个例子:太阳耀斑爆发这类自然现象,它产生的高速粒子流,会冲击地球的磁场,导致地球磁场发生变化,具体的原理,可以自行百度搜索。
- 网络堵塞
首先我们要知道,网络世界是通过 路由器/交换机 进行构建的。
路由器和交换机,我们可以比作一个一个的十字路口。
传输的数据,我们可以看作汽车,或者说,车流量。
现实生活中,当车流量过大的时候,就会发生堵车,网络传输有没有可能,也会发生堵车呢?
答:有这种情况。
某个时间点,实际需要转发的数据量,超过了设备能够转发传输的上限 ,此时,就会出现 " 堵塞 " ,造成丢包 。
这种情况在以前宽带传输速率比较低的时候,比较常见,例如:宿舍四个人,共用一个传输速率比较低的宽带,当有一位兄弟在下载游戏的时候,其他人的网络就会很卡。这种情况就是,下载游戏这个任务,把带宽的资源占用大部分,其他三位同学进行网络通信的时候(看视频,听音乐),网络通信会受到影响,出现丢包的情况
如果是网络拥堵,
情况好的话:数据包就会消耗更多的时间,才能到达对方。
情况坏的话:数据包太多太多,路由器/交换机,处理不过来,接收缓冲区,也满了,就只能丢弃最新的数据包了。
而且,网络上的数据包 ,都是有时效性 的。
假设,请求在规定时间内,没有到达服务器 ,就会出现 访问超时 的情况。
解决丢包:重传
丢包这件事,是无法避免的客观现象 。
对付丢包的手段就是:重传。
假如重传,还是丢包呢?
这种情况,也有,只不过,比较少,因为重传的次数越多,数据包能到达对方的概率,就会增多。
假如,我们发送一个数据包,当前的丢包率是 10%,数据包能到达对方的概率为 90%。
假如,第一次传输,丢包了,我们进行重传,一个数据包,连续发送两次。
根据概率论的知识,连续发两个包,两个包都丢的概率为 10% * 10% = 1%
至少有一个到达对方的概率为 99%
重传的次数越多,数据包能到达对方的概率,就会增多。
判断丢包:引入超时时间
如何来判断 ,这次的数据传输,是否发生丢包 了?
答:引入超时时间
一般,发送方发送数据给接收方,TCP 会设置一个超时时间 ,如果 接收方,经过这个超时时间,没有返回 ack(应答报文) ,发送方就会认为 ,传输过程中,发生丢包了。
TCP中,判定超时的时间阈值 ,不是固定数值,而是动态改变的。
假设,当前,A 给 B 发送数据,丢包的超时时间阈值为 T 。
当 A 给 B 传输发生超时 了(发生丢包 了)
就会延长这个时间阈值 (进行重传)
如果还发生超时情况(丢包 情况),会继续延长这个超时时间(再次重传 )。
当然,这个超时时间,不是无穷无尽的。超时次数到达一定次数(丢包次数) 或者 时间阈值到达一定程度(重传次数) ,就会认为:网络出现严重故障,放弃这一次的数据传输。
随着我们不断的延长这个时间阈值(多次重传 ),数据能到达对方的概率,是越来越高的 。
如果多次重传,还不能到达对方 ,说明:
当前的丢包率仍然是一个非常高的数据。意味着,网络上大概率已经出现严重故障 了。
都已经出现严重故障,就没有必要重传了 ,意义不大,就直接丢弃这个数据了。
2.2 两种情况

丢包的情况,可能有两种:
- A --> B 发送的数据,丢了,B没有接收到数据
- B --> A 返回的 ack 丢了,A没有接收到 ack
这两种情况,发送方是区分不了,当前是哪种情况,但是,做法都是一样的,都是进行重传。
下面,这两种情况,分别讨论:
A --> B 发送的数据丢了

这种情况,很好解决,数据丢了,直接重传就可以了。
B --> A 返回的 ack 丢了,A没有接收到 ack

这种情况,数据已经被 B 收到 了,B 这边,已经有 1~1000 的数据了。
ack 丢失,会触发重传,重传之前 1~1000 的数据 ,B 会收到两份一样的数据。
如果这种情况,TCP不进行处理,可能会使应用层读到两份一样的数据 。
如果是 扣款数据,这就不得了了,相当于你付一次款,扣两次相同的费用,这对用户来说,是巨大的损失。
TCP会在内部,进行去重操作 。
之前我们说,TCP会在接收方这边,安排一块 接收缓冲区,TCP会根据序号,在接收缓冲区中找。
如果接收缓冲区中,存在 相同序号的数据,就直接丢弃 。
如果接收缓冲区中,不存在 相同序号的数据,就将数据放入接收缓冲区。
去重
注意:去重操作 ,和第一个机制(确认应答 )中提到的排序 ,在接收缓冲区中,是同时进行的。
相当于,排序的时候,会根据序号,将数据放到对应的一块空间上 ,如果这块空间上,已经有相同序号的数据 了,就会丢弃这个数据 。
去重和排序,同时进行。
我们之前说,为什么 32位确认序号 的编号规则是:把收到的数据载荷的最后一个字节序号 + 1,填写到确认序号中?
按照这种编号规则:
当 ack 丢包之后,A 触发重传,再发送的一份数据,也是序号为 1-1000 的数据。
这样,就能够进行序号对比,一一去重。
序号为 1 的数据,已经有了,重传的数据中,序号为 1 的,就可以舍弃。
序号为 2 的数据,已经有了,重传的数据中,序号为 2 的,就可以舍弃。
......
如果,确认序号是这次数据的最后一个序号呢?
下次数据传输,从确认序号开始编号,序号为 1000-2000 的数据,此时,接收缓冲区,仍然会进行去重。
此时,接收缓冲区这边,看到序号1000 的数据,是已经有了,就会去重。
但是,之前序号1000 的数据,是第一次传输的数据 。
本次序号1000 的数据,是第二次传输的数据 。
如果去重 (本质就是覆盖),就会导致,第一次传输的数据,出现缺失,数据错误。
第三次数据传输,也会出现这样的数据缺失。
这就是为什么,32位确认序号 的编号规则是:把收到的数据载荷的最后一个字节序号 + 1,填写到确认序号中 。
这样的设计,不会导致错误去重。
3. 确认应答 & 超时重发 实现可靠传输
确认应答,超时重传,是TCP协议中,最核心的两个机制。
正是 确认应答,超时重传 这两个机制 ,才能保证 TCP协议,能够进行可靠传输 。
而可靠传输,是 TCP协议,最具有鲜明特色的机制(功能)。
为什么要专门强调这点?
因为网上有些资料说:保证 TCP协议 可靠传输的关键机制是 "三次握手" 。
这种说法,是错误(❌)的。
确认应答:确保数据是否到达了接收方
超时重传:确保在丢包的情况下,尽量能让对方收到该次数据
什么是三次握手???
这是 TCP建立连接 的流程。
在这篇博客中进行介绍:
网络原理(14):TCP协议十大核心机制 -- 建立连接(三次握手,四次挥手)
4. 总结
这篇博客,我们主要是介绍了TCP协议十大核心机制中的两个:
- 确认应答
- 超时重传
这两个机制,是实现可靠传输的最核心的两个机制。
TCP协议的十大核心机制,我们在这篇博客中,会放博客链接,你点击进去这篇博客:
网络原理(12):传输层 -- TCP协议的报文格式 & 十大核心机制的博客目录
就可以看到了。
最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!