TCP 糊涂窗口综合症

1、什么是TCP 糊涂窗口综合症?

TCP 报文首部就占 20 字节了,如果每次接收方只允许发送方发送两三个字节,那就为了传输这么几个有效的字节,还得附加上 20 字节的数据,这就是很浪费资源性能的。 这就是所谓的“TCP 糊涂窗口综合症”。
所以 TCP 糊涂窗口综合症(Silly Window Syndrome, SWS)简单来说,其实就是接收方接收能力变差,窗口变小,导致发送方犯傻,其发送的数据只有一个大大的头部,真正携带的数据很少。

2、如何解决TCP 糊涂窗口综合症?

从接收方维度解决

接收方的策略很简单,目的就是防止发送方发送小数据嘛

  • 那只要窗口大小 < 某个值(内核缓冲区大小的一半,也称为 最大段长度 MSS)的时候,就直接将窗口大小设置为 0,防止发送方发送小数据(注意这里区分下内核缓冲区(buffer)和 CPU 缓存(cache)的概念 窗口的大小的本质是内核缓冲区的大小
  • •然后等到窗口大小 >= 内核缓冲区大小的一半 的时候,才打开窗口,通告发送方,告知其可以发送数据。

这样就阻止了发送方发送小报文了。

还有一种方法,称为 “延迟确认应答

我们知道接收方窗口大小的变化过程是下面这样的

  • 接收方根据缓冲区空闲的空间大小,计算出后续能够接收多少字节的报文(即接收窗口的大小)

  • 当内核接收到报文时,将其存放在缓冲区中,这样缓冲区中空闲的空间就变小了,接收窗口也就随之变小了

  • 当进程调用 read 函数后(将数据从内核缓冲区复制到用户/进程缓冲区),报文数据被读入了用户空间,内核缓冲区就被清空,这意味着主机可以接收更多的报文,接收窗口就会变大

如果接受数据的主机在接收到报文的时候(第二步)就立刻返回 ACK 应答,这时候返回的窗口可能比较小。为什么这么说呢,举个例子:

  • 假设接受方主机的内核缓冲区大小为 1M,一次性收到了 500K 的数据,如果在第二步就立刻回复应答,那么返回的窗口大小就是 500K

  • 但实际上可能第三步处理得速度很快,很快就把 500K 数据从缓冲区消费掉了

  • 所以,如果接收方稍微等一会再应答,那么这个时候返回的窗口大小就是 1M,这样,发送方能够发送的数据是不是更多了呢~ ,这就是延迟确认应答。

这表示当一个报文段到达时并不立即发送确认。接收端在确认收到的报文段之前一直等待,直到入缓存有足够的空间为止。延迟的确认防止了发送端的TCP滑动其窗口。当发送端的TCP发送完其数据后,它就停下来了。这样就防止了这种症状。迟延的确认还有另一个优点:它减少了通信量。接收端不需要确认每一个报文段。但它也有一个缺点,就是迟延的确认有可能迫使发送端重传其未被确认的报文段。可以用协议来平衡这个优点和缺点,例如定义了确认的延迟不能超过500毫秒

也确实没有必要对每一个数据段都进行确认应答,毕竟用的滑动窗口(累计应答),应答少一些也无妨。在 TCP 文件传输中,绝大多数都是每两个报文段返回一次确认应答:

在这里插入图片描述

从发送方维度解决

发送方的目的也很简单,就是不要犯傻去发送小报文就行了

常用的策略是 Nagle 算法

该算法是指发送端即使还有应该发送的数据,但如果这部分数据很少的话,则进行延迟发送的一种处理机制。

具体来说,就是仅在下列任意一种条件下才能发送数据

  • 已发送的数据都已经收到确认应答时

  • 可以发送的数据大小 >= MSS(最大报文长度)

如果两个条件都不满足,那么发送方就是囤积数据,等待一段时间后再进行数据发送。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java全栈研发大联盟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值