文章目录
TCP
TCP连接如何确保可靠性
有一系列的机制来保证可靠性
确认应答
发送数据包后,回复ACK包,告诉对方确认收到
序号与确认序号
每个数据包都分配序号, 用来区分每个数据包和ACK
ACK带上确认序号, 表示这个序号之前的数据已收到
根据序号乱序重排, 确保双发收发数据一致
超时重传
数据包可能丢失, 发送方发送数据包后等待ACK, 若一段时间没有等到, 就重传
滑动窗口
接收方按序号缓存数据, 收到乱序的包先存起来, 等缺失包补齐之后再上交给应用层
快速重传
如果多次收到同一个确认序号的ACK, 立即重传改包, 无需等待超时
流量控制
接收方可以告知对方自己的发送能力, 调整窗口大小, 防止数据包被淹没
拥塞控制
更具网络拥堵状况, 动态调整窗口大小, 避免网络拥堵
确认应答
是什么
确认应答类似对话中的"嗯", 点头, 没有实际的意义, 表示回应.
在网络中就是接收方在收到TCP数据包后, 返回一个没有载荷, 只有报头的数据包回应, 表示确认收到
为什么
因为网络通信通常是乱序, 所以需要有办法识别和排序数据包, 因此需要引入序号和确认序号
序号与确认序号
序号是什么
TCP是面向字节流的, 每一个字节都有自己的编号
这些编号是连续的, 递增的
TCP报头的序号就是TCP数据包载荷的第一个字节的编号
确认序号是什么
表示的是在这个字节之前的所有数据已经全部收到
确认序号是应答报文(ACK)中的有效字段
当且仅当ACK字段为1时才会生效
具体含义是收到的最后一位+1
为什么
上一个数据包和下一个之间可以无缝拼接的
当接收方收到包之后可以根据序号排序, 确保收发一致
超时重传
是什么
当接收方在一段时间内没有收到应答ACK报文时, 就会认为数据包已丢失, 重新发送数据包
为什么
丢包有两种, 一种是ACK丢了, 一种是数据包丢了
发送方方没办法辨别
统一重发数据包
接收方有一个接收缓冲区
如果收到重复的数据包, 直接丢弃即可
连接管理
三次握手(建立连接)
握手是什么
握手就是对话前的打招呼, 在网络中是只有报头的数据包, 没有载荷
建立连接的过程
发送方发送SYN请求建立连接
接收方返回SYN+ACK同意建立连接
发送方再返回ACK表示建立连接完成
实际上是四次, 中间的SYN和ACK合并成了一次
意义
验证链路是否通畅
确认双方收发能力是否正常
协商参数, 比如起始序号, 防止过期数据包影响发送
四次挥手(断开连接)
挥手是什么
就是双方各自删除对方的信息, 彻底断开连接
断开连接的过程
主动方发送FIN报文请求断开连接
对方方返回ACK, 确认收到断开请求
对方发送FIN, 表示自己也要断开
主动方发送ACK, 表示断开成功
为什么不能合并
因为三次握手ACK和SYN都是由内核自动处理的, 时机一致, 可以合并
四次挥手中的ACK是内核处理的, FIN是由应用程序触发的(比如close), 时机不一定一致, 所以不能合并
滑动窗口
是什么
滑动动窗口就是批量发送数据的一种形式
为什么
没有滑动窗口, 就是一发一答, 比较低效
有滑动窗口, 就是发送一批数据, 等待一批ACK, 把多次等待ACK的时间合并成一份, 所以更高效
工作原理
假设一组数据 1-1001-2001-3001-4001-5001
滑动窗口为1-4000, 大小为4000, 表示的含义是 发送1-4000的数据, 接收1-4000的ACK
当收到1001的ACK时, 就立即发送4001的数据包, 窗口为1001-5000, 窗口大小不变, 窗口右移
丢包如何应对
滑动窗口的前提是可靠性
丢包分为两种, ACK丢包和数据包丢包
ACK丢包
不用处理, 因为ACK的含义是到这个字节前的数据已全部收到
下一个ACK的含义可以涵盖上一个
因为是等待一批ACK, 会丢失一部分, 不可能全丢
后面的ACK可以弥补前面的丢失, 无需重传
数据包丢了
假设发送1数据包, 返回ACK1001
发送1001数据包, 丢包
发送2001数据包, 由于没有1001-2000, 返回的ACK仍然是1001
发送3001数据包, 返回的ACK还是1001
这时连续三次返回ACK1001, 发送方意识到1001包丢了
立刻重传1001
当接收方收到1001包后, 补齐了1-4000的缺口, 返回ACK4001
表示下一个从4001开始发
快速重传
这就是快速重传机制, 是搭配滑动窗口用的
快速识别哪个数据包丢失, 针对性的重传
流量控制
是什么
流量控制是限制发送方的发送速度, 根据接收缓冲区大小来动态调整窗口大小
为什么
因为通信是双方的事, 发送方发送的快了, 接收方要有能力处理
具体原理
接收方有一个接收缓冲区, 这个缓冲区类似阻塞队列, 生产消费者模型
如果发送方发送特别快, 接收方处理的慢, 缓冲区就会满, 如果再强行发送数据, 就会导致丢包
这就需要根据接收方的处理速度来制约发送方的发送速度
缓冲区空闲空间小, 接收方处理能力弱, 减小窗口, 限制发送方发送
缓冲区空闲空间大, 接收方处理能力强, 增大窗口, 允许发送方多发送
TCP中的反馈机制
接收方在接收到数据后, 会把缓冲区大小, 通过ACK反馈给发送方
当ACK标志位=1时, 窗口大小字段才有效
缓冲区满了该怎么办
当缓冲区满了, 窗口大小=0, 双方停止发送, 陷入等待
发送方会定期发送窗口探测包, 触发ACK反馈, 询问窗口大小
接收方在处理了一些数据后, 窗口变大, 会主动发送窗口更新通知数据包, 让发送方恢复发送
拥塞控制
是什么
也是限制发送方发送速度, 是从传输链路的视角来看的
基本思想
把传输链路的中间节点(比如路由器, 交换机)视为一个整体, 不关注内部细节, 通过动态调整窗口大小来找到合适的发送速度
窗口变化过程
初始阶段:慢启动
刚开始拥塞窗口很小,发送的速度很慢, 因为网络拥堵情况未知, 先小心试探
指数增长:
没有丢包, 说明网络通畅, 窗口指数增长, 以比较短的时间增长到较大的窗口
线性增长:
当窗口增长到一个阈值后, 即使没有丢包, 也会停止指数增长, 变为线性增长, 防止增长太快导致突然拥堵
出现丢包:减速和窗口调整
当出现丢包时, 说明网络拥堵, 此时减小窗口大小, 减慢发送速度
窗口变为新的阈值, 然后线性增长(不再指数增长)