TCP 的流量控制

TCP 的流量控制

为什么要控制TCP传输流量呢?难道数据传输越多不好吗?那么我们就来讨论一下接收过程
在这里插入图片描述

假设主机A应用要发送数据hello给主机B,应用先把数据发送到主机A TCP发送缓冲区中,TCP在合适的时间再将数据将hello发送至主机B的TCP接收缓冲区中,然后主机B的应用从TCP接收缓冲区中取出hello数据

问题由以下几点

  • 主机B的接收缓存区可能很小,根本接收不了hello这么多数据
  • 主机B的接收缓存区满了,应用还未来得及取走数据,又有新的数据到来了
  • 反之,发送方也对应相应的问题。如:发送的太快等。
  • 在缓冲区足够大的情况,发送很多数据,可能会导致网络很拥挤

上述问题将导致数据丢失,因为没有空间存储下来,而且也成功收到了。所有综合上述,TCP必须对数据流量进行控制,通过滑动窗口实现。

利用滑动窗口实现流量控制

A 向 B 发送数据。在连接建立时,B 告诉 A:“我的接收窗口 rwnd = 400(字节)”。

举例
在这里插入图片描述

分析

  1. B先告诉A自己只能接收400字节大小的数据
  2. 当B向A发送ACK = 1, ack = 201, rwnd = 300消息时,有两点重要的消息,一)下一次接收数据的开始序列号是201;二)只能接收300字节大小的数据(A只能发201~500的数据),此时窗口大小有调整
  3. 当B向A发送ACK = 1, ack = 501, rwnd = 100消息时,有两点重要的消息,一)下一次接收数据的开始序列号是501(A只能发501~600的数据);二)只能接收100字节大小的数据,此时窗口大小有调整
  4. 当B向A发送ACK = 1, ack = 501, rwnd = 100消息时,有两点重要的消息,一)下一次接收数据的开始序列号是501(A只能发501~600的数据);二)只能接收100字节大小的数据,此时窗口大小有调整
  5. 当B向A发送ACK = 1, ack = 601, rwnd = 0消息时,有两点重要的消息,一)下一次接收数据的开始序列号是601(但是不能发送数据,没有空间接收数据);二)没有空间接收数据,此时窗口大小有调整

上述只是单向说明,反之亦然。可以看出滑动窗口可以实现流量控制

我们来分析一种异常情况
在这里插入图片描述

B 向 A 发送了零窗口的报文段后不久,B 的接收缓存又有了一些存储空间。于是 B 向 A 发送了 rwnd = 400 的报文段。但这个报文段在传送过程中丢失了。A 一直等待收到 B 发送的非零窗口的通知,而 B 也一直等待 A 发送的数据。如果没有其他措施,这种互相等待的死锁局面将一直延续下去。

因为A在等B更改窗口大小(B其实通知更改窗口大小,A以为没通知更改窗口大小),B在等A发送数据(B其实通知更改窗口大小,以为A收到了,自己会收到数据)

如何解决?,可以借鉴超时重传的思路,可以为每一个TCP 连接设有一个持续计时器
只要 TCP 连接的一方收到对方的零窗口通知,就启动该持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带1字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。

  • 若窗口仍然是零,则收到这个报文段的一方就重新设置持续计时器。
  • 若窗口不是零,则死锁的僵局就可以打破了。

TCP 的传输效率

接下来将讨论效率问题,由于TCP传输最小需要20字节的首部信息,那么我们的数据大小多大合适呢?
在这里插入图片描述

显示太小不合适,那么太大可以吗?也不行,IP层会分包,数据链路层有最大输出单元等等限制。那TCP是如何决定传输多大的数据单元呢

可以用不同的机制来控制 TCP 报文段的发送时机:

  1. 第一种机制是 TCP 维持一个变量,它等于最大报文段长度 MSS。只要缓存中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去。
  2. 第二种机制是由发送方的应用进程指明要求发送报文段,即 TCP 支持的推送 (push) 操作。
  3. 第三种机制是发送方的一个计时器期限到了,这时就把当前已有的缓存数据装入报文段(但长度不能超过 MSS)发送出去。

方便记忆:即为空间/时间/人工干预三个角度控制数据大小

糊涂窗口综合症

糊涂窗口综合症:每次仅发送一个字节或很少几个字节的数据时,有效数据传输效率变得很低的现象
在这里插入图片描述

发送方糊涂窗口综合症

发送方 TCP 每次接收到一字节的数据后就发送。这样,发送一个字节需要形成 41 字节长的 IP 数据报。效率很低。

如何解决呢?Nagle 算法

  • 若发送应用进程把要发送的数据逐个字节地送到 TCP 的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。(测试功能,方式发了很多数据结果收不到)
  • 当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。
  • 只有在收到对前一个报文段的确认后才继续发送下一个报文段。(串行发送,所有有延迟问题,不及时)
  • 当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。

11

接收方糊涂窗口综合症

当接收方的 TCP 缓冲区已满,接收方会向发送方发送窗口大小为 0 的报文。;若此时接收方的应用进程以交互方式每次只读取一个字节,于是接收方又发送窗口大小为一个字节的更新报文,发送方应邀发送一个字节的数据(发送的 IP 数据报是 41 字节长),于是接收窗口又满了,如此循环往复。
在这里插入图片描述

解决方法:让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值