文章目录
- 前言
- 一、确认应答
- 1, 什么是确认应答
- 2, 序列号和确认应答号
- 二、超时重传
- 1, 什么是超时重传
- 总结
前言
各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你:
📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等
📗 Java数据结构: 顺序表, 链表, 堆, 二叉树, 二叉搜索树, 哈希表等
📘 JavaEE初阶: 多线程, 网络编程, TCP/IP协议, HTTP协议, Tomcat, Servlet, Linux, JVM等(正在持续更新)
TCP 协议是一种有链接的可靠传输协议, 并且 TCP 设计的宗旨是保证可靠性的同时, 尽可能地提高传输效率, 因此 TCP 具有八大机制 :
- 1️⃣连接管理(三次握手 + 四次挥手)
- 2️⃣确认应答
- 3️⃣超时重传
- 4️⃣滑动窗口
- 5️⃣流量控制
- 6️⃣拥塞控制
- 7️⃣延迟应答
- 8️⃣捎带应答
看不懂吧, 没关系, 我会出手, 先记住2~3 用来保证可靠性, 4~8 用来提高效率
上篇文章介绍了连接管理机制(三次握手四次挥手)
很多人都误以为连接管理机制也是用来保证可靠性的, 其实并不是
UDP 协议是无连接传输, 因此使用 UDP 协议协议传输数据, 发送方甚至不关心对端是否能接收, 不做任何检查就一股脑发出去了, 而 TCP 则不然, TCP 实现了在通信之前先建立连接, 通信完了再断开连接, 所以连接管理机制仅仅是通信前的"检查"
本篇就来介绍 TCP 保证可靠性的确认应答机制和超时重传机制
提示:是正在努力进步的小菜鸟一只,如有大佬发现文章欠佳之处欢迎批评指点~ 废话不多说,直接上干货!
一、确认应答
之前的文章就提到过, TCP协议的可靠性不是说确保每次发送数据都能 100% 能成功, 而是如果发送失败, 发送方会知道自己发送失败
如何做到呢? 正是因为有确认应答机制
1, 什么是确认应答
是指 : 如果接收方收到了数据报, 由操作系统内核来返回一个 ack (确认应答报文)
确认应答最明显的作用就是 : >如果发送方收到了 ack, 视为数据发送成功, 如果没有收到 ack, 就视为数据发送失败
确认应答机制有三种情况, 如图 :
第一次发送数据, 发送方收到了 ack, 视为发送成功
第二次发送数据, 数据报半路丢了, 接收方当然不会返回 ack, 发送方没有收到 ack, 视为发送失败
第三次发送数据, 接收方确实收到了数据报, 但是 ack 半路丢了, 发送方没有收到 ack , 也视为发送失败
ack 也是数据报, 数据报半路丢了的情况, 称作"丢包"
2, 序列号和确认应答号
实际上, TCP 的报头格式中包含两个字段 : (发送方的)序列号和 (接收方的)确认应答号
序列号是指 : 给发送的数据的每一个字节标号, 第一个字节就是该数据报的序列号
确认应答号是指 : 接收方已经收到的序列号 + 1, 来表示下次应该收到的序列号
上图中第一个数据报发送之后, 接收端已经收到了序列号为1000之前的所有数据, 返回 ack 中的确认应答序号为 1001 的意思就是"我该接收序列号为 1001 "的数据了
TCP数据报的实际长度可能并不是1000字节, 并且序列号的初始值是一个随机数
序列号和确认应答号最明显的作用就是, 让发送方知道接收方已经收到了哪些数据, 还有其他作用, 后续介绍其他机制时慢慢补充
二、超时重传
如果网络通畅, 一切顺利的话, 通过确认应答就能很好的保证并确认数据成功发送, 但是难免会有网络拥堵或其他原因导致丢包
可能是发送的数据丢包, 也可能是 ack 丢包, 无论那种情况, 发送方都不能及时地收到 ack , 所以视为发送失败, 这种情况下为了保证可靠性, 超时重传机制就做出了补救
1, 什么是超时重传
是指 : 一定时间内, 发送方没有收到接收方返回的 ack , 就尝试再次发送数据
也就是说, 发送方发完数据之后会等 ack , 等一会之后没等到, 就重发. 当然重发的数据也有可能再次丢包导致没收到 ack , 那就多等一会, 总之, 每次重发都会指数形式延长等待时间
难道要一直重发吗? 发送方重发多次还收不到 ack, 基本上是网络或者对端主机有异常, 发送端会主动断开连接
名言 : 难办? 那就**别办了!
超时重传不成功的情况 :
每次等待的时间都会以指数形式增长, 包括最后主动断开连接, 这都在一定程度上避免了网络流量浪费
超时重传成功的情况 :
所以, 如果是网络或者对端主机没问题, 偶尔一次小概率的丢包, 通过超时重传就可以保证可靠传输
需要注意的是, 上图中虽然由于超时重传机制成功发送了数据, 但是接收方收到了两份序列号为 1 的数据报, 难道接收方的应用程序会读取两次吗?
并不会, 因为接收方的接收缓冲区会根据序列号进行去重, 保证同一份数据只读取一次, 上述过程其实也有"序列号和确认应答号"的作用
总结
以上就是本篇的全部内容, 主要介绍了确认应答机制和超时重传机制, 这两个机制保证了 TCP 协议传输时的可靠性
策略是 : 如果一切正常, 通过确认应答机制保证接收方收到了数据, 如果丢包, 通过超时重传及时补救
如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦😋😋😋~
上山总比下山辛苦
下篇文章见