|
JavaEE
网络原理——No.1 传输层_TCP的确认应答机制与超时重传
网络原理——No.2 传输层_TCP的连接管理
TCP
能够保证可靠传输, 但是却增大了开销. TCP 的传输效率一般是低于 UDP
的.
TCP
希望能够在保持可靠性的前提下, 尽可能的提高传输效率(但这里无论如何在效率上不可能超过 UDP
).
滑动窗口 就是提高 TCP 传输效率的有效机制.
提升效率的方式, 就是不等 ACK
了 (确实是不等, 但不是完全不等), 直接往下发下一条. 每次批量的发送一波消息, 然后再等一波 ACK
, 再发一波消息.
滑动窗口
#
窗口大小: 把不需要等待, 就可以直接的发送的数据的量, 就成为 “窗口大小”
# 注意 #
主机 A 收到一个 ACK
就继续发一条数据, 而不是等所有的 ACK 都到了, 再发送数据.
在 2001 这个 ack
到达之前, 主机A上待确认的数据是 1001-5000, 在2001 到达之后
意思是 1001-2000 就确认发送成功了, 于是就把 1001-2000 这个个记录从白色的框里删掉了
同时又发送了 5001-6000 这个数据, 因此就需要继续等待 5001-6000 的 ack
此时要等待的数据仍然是 4 条, 看起来就好像是 白色的框长度没变,整体向右挪了一步.
# 注意 #
- 效率高不高, 取决于窗口的大小, 窗口越大, 效率就越高. 窗口越小, 效率就越低
- 假设窗口无限大, 此时发送就完全不需要等待 ACK 了, 此时效率就和 UDP 一样了, 但这样可靠性就无法保证了
丢包分为两种情况
- 响应的 ACK 丢了
- 传的数据丢了
响应的 ACK 丢了
比如: (后者包含前者) 类似于有, 大学毕业了, 说明你的高中和初中早已毕业了.
传的数据丢了
前面丢的是 1001-2000. 而 2001-7000 这些数据没丢, B 都收到了, 但 B 始终差了 1000-2000
这块.
当 A 重传了 1001-2000 之后, 此时 7000 之前的数据都被补齐了. 因此, B 自然就从 7001
开始索要即可.
在上述设定中, 只是把丢的数据报进行了重传, 没丢的包, 没有重传
上述的重传过程中, 效率也是比较高的 “快速重传”(搭配滑动窗口的超时重传)
# 注意 #
不是说有了快速重传, 超时重传就没意义了.
如果传输的数据很多, 批量重传, 此时自然是遵守快速重传的方式
如果传输的数据很少(就只有一条), 此时仍然是按照超时重传的方式来进行的
如果正是最后一个丢了, 还是按照超时重传的方式来进行即可
窗口大小越大, 确实发送速度会更快, 但是窗口能无限大吗?
如果我们发送的过快, 接收方处理速度, 跟不上, 就会导致接收方就丢弃一部分数据.
而TCP 是要保证可靠性, TCP 还得重传这些数据.
这时我们就需要再有其他的机制, 来对发送方的发送速度, 作出限制——流量控制
在滑动窗口的基础之上, 对发送速率做出限制的机制, 就是限制发送方的窗口大小不要太大.
窗口大小多少合适呢? 问问接收方, 看接收方觉得发多快合适.
流量控制本质上, 就是接收方对发送方的反制, 接受方根据自己的接受能力, 来反向影响发送方接下来的发送速率.
接收方的接收速率, 如何进行量化?
接收方使用接收缓冲区的剩余空间大小, 来作为发送方发送速率(窗口大小) 的参考数值.
类似生产者消费者模型
A 是生产者, 往 B 的接收缓冲区生产数据, B 的应用程序, 从接收缓冲区中消费数据.
如果我们把缓冲区想象成一个蓄水池
接收方 B 收到 A 的数据, 就会在 ack 应答报文中, 把当前接收缓冲区剩余空间大小的值, 反馈给发送方.
16 位 能表示的最大数字就是 64kb ,是否意义着滑动窗口最大就是 64kb?
不是! ! TCP 报头的选项
中, 会有一个特殊的值, 窗口大小的扩展因子, 可以通过扩展因子来表示更大的值.
❗这时出现了一个问题:
如果 A 不发送数据 B, B 就没法返回ACK
如果 B 不返回 ACK , 后续缓冲区里有空闲空间, 如何告知 A 呢❓
流量控制, 是通过接收方的处理能力, 来衡量发送方的速率的.
刚才只是考虑了接收方的处理速率,难道发送方就可以随便发了吗?
显然不是, 还需要考虑中间的这些转发节点的情况. (接收方, 处理速率, 是最容易量化的. 但是中间节点, 情况难以量化)
我们应该如何考虑中间节点呢?
思路:
把中间的这些设备, 视为一个 “整体
”, 我们通过 “做实验
” 的方式, 来验证发送速度多少合适
开始的时候, 发的慢点, 如果一路顺畅, 就是放的提高一下速度
提高到一定程度之后, 发生丢包, 再降低一下速度
降低速度之后, 发现又通畅了. 再提高速度. 达到一种 “动态平衡
”
流量控制, 控制发送方的窗口大小
拥塞控制, 也是控制发送方的窗口大小
谁的数值小听谁的
TCP 实现拥塞控制具体方式
TCP
引入慢启动机制, 先发少量的数据, 发送之初, 网络情况前路未知.指数
增长(翻倍), 达到阈值, 就线性
增长 [短时间内, 摸清楚网络传输承载的底线]阈值
, 达到阈值就不再指数增长了为什么是一半呢?
阈值之前是翻倍的, 如果新的阈值比丢包窗口/ 2 还大, 那就意味着, 指数增长的翻倍直接就超出阈值了.
因此我们的阈值是在动态调整的(根据网络的情况)
小知识:
上述过程, 是 TCP
传统的拥塞控制实现的, 后来 TCP
也在进行演化, 拥塞控制也做出了一些改进.
其中的改进就是, 回归不再回归到初始值, 而是回到一个中间的值.
|
以上就是今天要讲的内容了,希望对大家有所帮助,如果有问题欢迎评论指出,会积极改正!!