TCP 协议
1.确认应答 可靠传输的核心机制
2.超时重传 可靠传输的核心机制
3.连接管理 TCP/网络 最高的面试题
三次握手,建立连接(必须是 三次)
四次挥手,断开连接(可能是 三次)
核心机制四:滑动窗口
算法中的"滑动窗口" 出自 TCP
前面的三个机制,实现 TCP 的"可靠性",滑动窗口,是提高效率
可靠性是要付出代价的,传输效率的降低
每次发一个数据,都要等 ack..单位时间内能传输的数据就少了
每一份等待都是等一个 ack 的到达
把每次发送都等待 ack => 批量发送一波,在等待 ack(花一份的等待时间,等待多个 ack)
等待的一份时间中,就是在等待 4 组 ack 的到达,肯定不能完全不等(可靠性形同虚设了),就把批量发送多少数据不需要等待 称为"窗口大小"
问题是,发送方,是收到 4 个 ack,再继续往后 4 组数据?还是收到 1 个 ack,就立即往后发 1组数据(正确)
1001 - 5001 等待四组 ack
A 收到 2001 ack 就视为 1001 - 2000 已经收到了,就可以立即发送 5001 - 6000,此时等待 ack 的窗口就变成了 2001 - 6000
每次收到一个 ack,窗口都会往后平移一个格子,如果收到 ack 的速度很快,平移的过程就好像"滑动"的过程
滑动窗口的效率提高,本质是"亡羊补牢""止损",再怎么提高,也不会超过 UDP 无可靠传输机制的协议的
最理想的状态下,TCP 和 UDP 速度相当,不可能因为滑动窗口让 TCP 比 UDP 更快\
滑动窗口的机制下,出现丢包,怎么办?
情况一:数据包已经抵达,ACK 被丢了
后一个 ack 会覆盖前一个 ack
如果只是 ack 丢包, 在滑动窗口机制下,不需要做任何处理!!!
ack 的确认序号的设定规则
ack 的确认序号,表示序号之前的所有数据都已经收到了,ack => 1001, 1001 之前的数据都收到了
情况二:数据包直接丢了
B 向 A 索要 1001 这个数据
B 反复向 A 索要没有收到的 1001 这个数据, A 感知到 B 连续多次索要 1001 之后,就会认为 1001 丢包,触发重传 1001
一旦 1001 - 2000 数据 B 收到了,此时 B 观察发现,自己的接受缓冲区里,已经有 2001 - 7000 这些数据了,接下来从 7001 索要即可
快速重传(滑动窗口机制下的重传机制,相当于超时重传的变种)
滑动窗口(批量传输) 快速重传 和 确认应答 超时重传 关系
上面这两套,是共存的机制并不冲突
如果使用 TCP 传输比较大的数据的时候,自然就会触发,滑动窗口,重传机制采取快速重传
如果使用 TCP 传输较少的数据,此时就仍然是按照 确认应答 和超时重传 方式来进行
想象一下,TCP 的代码里,触发重传的条件有两个
1)连续多次收到同一个 ack
2)一定时间内没有收到 ack
触发重传