流量控制(为什么,协商接收能力,窗口探测,窗口大小),滑动窗口(如何实现区域划分,窗口如何移动,异常情况的处理,指针的值如何确定,与流量控制的关系),快重传(与超时重传的对比)

目录

流量控制

引入

协商接收能力

发送方式

为什么要分次发送 

窗口探测

引入

介绍

发送方

接收方

总结

窗口大小

总结

滑动窗口

引入

介绍

区域介绍

区域划分如何实现

窗口如何移动

滑动窗口会不会向左移动

异常情况的处理

应答丢失

数据丢失

总结

快重传

介绍

和超时重传的对比

总结

指针的值如何确定

是否会越界

滑动窗口与流量控制的关系


流量控制

引入

--tcp协议介绍,协议段格式(端口号,首部长度,窗口大小,序号,确认序号,6个标志位),流量控制,确认应答机制,捎带应答,三次握手的双方认知不一致问题-CSDN博客

在之前的博客里,我们已经介绍过,可以根据对方主机的缓冲区大小动态控制发送速度,用来防止大面积丢包

该如何保证第一次发送数据的大小的合理性呢?

协商接收能力

其实在三次握手期间,就已经协商了双方的接收能力

  • 别忘了三次握手就是在交换报文,不仅里面携带的标志位是重点,其他字段同样也是
  • 而且三次握手中的第三次,是可以携带数据的(捎带应答),因为一旦第三次成功,连接也就建立成功,通信本来就是顺理成章的事情 -- 这样可以提高通信效率
  • 说明在前两次的时候已经协商好了

发送方式

发送报文可以串行发送,也可以并行发送

当然也可以混用 

  • 并行 -- 网络信号好
  • 串行 -- 网络不好/需要进行管理动作
  • 根据网络情况/通信情况动态调整

为什么要分次发送 

其实,仔细想想,为什么要把这些数据分成一段一段的,打包成一个发过去不好吗,为什么要并行发送那么多个?单次io的效率还更快

  • 因为硬件--也就是网卡,不允许发送大块数据

 

窗口探测

引入

发送过程中,如果对方的接收窗口大小变为0

  • 根据流量控制,a主机就停止发送,等待对方的窗口大小更新(也就是等待对方应用层读取数据)

但是也不能一直等吧,所以有了窗口探测的机制

介绍

发送方

如果对方一直没有发送窗口更新通知,就会向对方发送一个窗口探测的包

  • 而tcp报文一定要确认,也就是返回应答,那么应答里一定携带报头->窗口大小字段
  • 这个过程中的报文只是一个报头,不需要携带数据,也就不存在因缓冲区不足而丢包的问题

如果网络出问题了,可能窗口探测报文无法成功传输

所以,不止发送方有策略,接收方也有相应的机制

接收方

b主机可以发送更新通知给对方(这里的报文也只是一个报头)

  • 可以更好地提高效率

如果这个问题只是单向的,那么更新通知就可以成功到达

总结

总之,这样双方都有相应的策略,就会有先到达的报文

  • 这样可以提高效率
  • 也可以防止出现单向网络出现问题,导致报文发不过来的情况,这是一种容错性

并且,这两种机制:

  • 窗口探测 -- 接收方的应答就是一种确认
  • 窗口更新通知 -- 发送方收到后会立即发送报文,相当于是通知的应答
  • 所以,这两种报文都有应答,可以确保对方是否收到

如果两个应答都没有收到

  • 就证明双方网络有问题
  • 重传一段时间后,连接就因异常直接退出

窗口大小

tcp中窗口大小字段为16位

  • 也就是说,窗口大小最大为2^16,大概是64k

而窗口大小用来描述接收缓冲区的剩余空间

  • 那么接收缓冲区最大就是64k?
  • 不一定,因为tcp首部40字节中的选项里,还包含了窗口扩大因子M

最终,实际的窗口大小为

  • 窗口大小字段的值<<M位,也就是窗口大小字段值 * 2^M
  • 所以,实际的大小取决于系统实现(是否设置扩充因子和是否支持)

总结

流量控制属于可靠性的一种

  • 防止正常报文的丢包
  • 同时也提高了效率 -- 不丢包->不重传->不使用过多的网络资源
  • tcp很多机制的设计都是这样
  • 比如:捎带应答,既保证了可靠性,又提高了效率

滑动窗口

引入

因为存在并行发送

  • 那么暂时没有收到应答的报文,需要tcp保存起来(方便之后的重传)

那势必这样的报文不止一个,这些报文被保存到哪里了呢?

  • 其实不需要单独再找个地方存放
  • 这些报文本来就是从tcp的发送缓冲区里拷贝到底层,让底层发送的
  • 我们只需要对这个缓冲区做一个区域划分 -- 已发送已确认,已发送未确认,待发送

 

介绍

区域介绍

已发送已确认

  • 可被上层覆盖,如果被覆盖,就相当于从tcp缓冲区中移除了
  • 计算机里不存在真正的清空,只要这块区域可以被覆盖,就说明这块区域数据是无效的

已发送未确认

  • 这块的报文不一定都发送了,是可以发 / 已经发,但尚未收到应答的区域
  • 如果收到应答,就将该报文纳入到已发送已确认的区域中
  • 如果还未收到,暂时不能被修改,这就相当于是在暂时保存了
  • 这块区域就叫做滑动窗口 -- tcp发送缓冲区的一部分
  • 这部分的数据是可以直接被推送给接收方

  • 而之前说的并发发送,正是因为有滑动窗口才能实现(需要一块区域作为暂存区,也需要一块区域来容纳可以直接发送的数据)

区域划分如何实现

缓冲区无非就是个数组

  • 区域划分直接通过数组下标实现
  • 很像我们的双指针算法,也像之前在虚拟地址空间里介绍的如何实现区域划分的一样,维护两个整数->一个区域
  • 窗口的滑动,本质上就是指针移动

窗口如何移动

一旦有报文被确定了

  • start就向右移动若干位

如果对方有更大的接收窗口了

  • end就向右移动

原则上来说,窗口越大,网络吞吐率越高

滑动窗口会不会向左移动

原则上不可以

  • 因为左侧是已确认已应答的,它没法把[已经应答过的数据]纳入[已发送未应答/可发送]的范畴
  • 右侧是待发送,它没法把[可以立即发送的/已发送的]又重新纳入到[待发送区]

接下来看看异常情况时,滑动窗口是如何处理的

异常情况的处理

应答丢失

如果发送了1000-5000的数据,其中2001-3000数据的应答丢失

  • 只是应答丢失,说明数据还是收到了
  • 那么收到的确认序号应该是5001 -- 确认序号允许少量应答的丢失
  • 所以滑动窗口的start直接右移到5001

那如果最后一个报文的应答丢失了怎么办

  • 因为我们之前都是依靠最后一个应答的确认序号,来判断哪些数据收到了
  • 那确认序号最大只能是4001,所以需要补发4001-5000的数据
  • 所以滑动窗口的start只能右移到4001(它指向最小序号的丢失报文)

如果应答全部丢失

  • 就只能全部补发,因为没有确认序号让我们判定

总之,应答丢失我们是可以正确更新指针的

数据丢失

假设还是2001-3000的数据丢失,其他报文都收到了+有应答

  • 那么收到的确认序号是:2001,2001,2001
  • 所以,需要补发2001之后的数据

总结

总之,根据确认序号的特性 -- 确认序号之前的数据都已经收到了 

  • 能保证滑动窗口是线性的连续向后更新,不会出现跳跃
  • 所以,确认序号的值可以正确指导滑动窗口的滑动

 

快重传

介绍

当出现丢包后,发送方可能会收到大量确认序号相同的应答:

如果收到3个同样的,就进行重发

  • 发送方可以通过确认应答的值判断出要重发的数据

重发后

  • 如果后面的报文都已经收到了,则应答的确认序号直接变成下一个数据包的序号:
  • 如果还有报文丢失,则更新为该丢失报文的序号:
  • (我们可以理解成接收方会有自己的方式记录下到底哪些收到了,哪些没收到,最终以确认序号的方式告诉对方)
  • 如果同一个确认序号累计出现三次后,继续进行补发

以上机制叫做快重传

和超时重传的对比

有了快重传,为什么还要有超时重传?

  • 需要保证可靠性

因为快重传是有条件的

  • 必须收到三个相同的才会触发
  • 如果一次没发送那么多数据,却有报文丢失怎么办 / 丢失的数据是倒数第二个/最后一个
  • 如果没有其他策略,这个报文丢失了就补不回来了

快重传是一种提高效率的策略

  • 可以让丢失的报文尽快重传,而不是等到超时再说

超时重传是用来兜底的

  • 没有触发快重传的丢失的报文,都会触发超时重传

总结

指针的值如何确定

这里就把滑动窗口的开始和结束认为是数组下标

start = 确认序号

  • 因为序号是一直在增长的,所以滑动窗口一直在右移

end = 确认序号 + min( 对方接收窗口大小,有效数据大小) 

 -- 注意,这里并不全面,在下一篇博客的"拥塞控制"中会介绍

  • 为什么要找到最小值呢?
  • 因为如果滑动窗口移着移着越界了怎么办?
  • 缓冲区本质上是个数组,也就有对应的范围
  • 而且,缓冲区其实不止三部分,在待发送区域的后面可能还有一部分区域,是还没有写入数据的部分,所以需要以是否是有效数据为界限

是否会越界

那它最终会越界吗?

  • 会的
  • 所以tcp采用了类似环状算法

缓冲区可以看作是基于数组的环形结构

  • 物理上是线性结构
  • 逻辑上是环形结构

当滑动窗口将要移动至缓冲区末尾时

  • end便更新为0
  • 刚好首尾部分(已确认区,未写入数据区)都是可写的,当上层写入数据时,如果缓冲区被打满了,就接着从起始位置写

 

滑动窗口与流量控制的关系

因为滑动窗口内存放的是可以直接给对方发送的数据

  • 所以通过滑动窗口大小的控制 -> 控制发送数据量的多少
  • 这也就实现了流量控制

流量控制不只是可以减缓发送速度,也可以增大

  • 取决于对方的接收能力 -> 调整滑动窗口 -> 控制发送数据量

  • 29
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值