TCP的滑动窗口

本文详细介绍了TCP的滑动窗口机制,包括引入滑动窗口的原因、累计确认机制以及窗口大小的决定因素。内容涵盖发送方和接收方的滑动窗口状态,窗口关闭与流量控制的关系,以及解决窗口关闭潜在风险的方法。同时讨论了小窗口问题的处理策略和Nagle算法在避免小数据报文传输中的应用。
摘要由CSDN通过智能技术生成

1. 引入滑动窗口的原因

  • 如果没有滑动窗口,TCP每发送一个数据,都需要等待这一次确认应答。只有收到了上一个数据包的应答,才能再发送下一个。这样效率太低了
  • 当引入了滑动窗口机制后,就可以采取累计确认机制
  • TCP引入了窗口这个概念,有了窗口,就可以指定窗口大小,窗口大小是指无需等待确认应答,而可以继续发送数据的最大值。
  • 如图,假设窗口大小是3个TCP段。即使ACK 600确认应答报文丢失,也没关系,因为可以通过下一个确认应答进行确认。只要发送方收到了ACK700确认应答,就意味着700之前的所有数据接收方都收到了。这就是累计确认

2. 累计确认机制

滑动窗口是缓存的一部分,用来暂时存放字节流。 发送方和接收方各有一个窗口,接收方通过TCP报文段中的窗口字段告诉发送方自己的窗口大小。发送方根据这个值和拥塞窗口信息来设置自己的窗口大小。

发送窗口内的字节都允许被发送,接收窗口的字节都允许被接收,如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离。直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动窗口类似,接收窗口左部字节已经发送确认并交付主机,就右滑动接收窗口。

接收窗口只会对窗口内最后一个按序达到的字节进行确认。例如接收窗口已经收到了字节为{31,34,35},其中31是按序达到,则只对31确认。发送方得到这个字节的确认后,就知道这个字节前面的所有字节都被接收了。

3. 窗口大小由哪一方决定

  • TCP头部有一个Window字段,指明了窗口大小
  • 这个字段是接收端告诉发送端自己还有多少缓存区可以接收数据。于是发送端就可以根据接收端的处理能力来发送数据,而不会导致接收端处理不过来

3.1 发送方的滑动窗口

  • SND.WND:表示发送窗口的大小(大小由接收方指定的)
  • SND.UNA:是一个绝对指针,指向已发送但未确认的第一个字节的序列号。
  • SND.NXT:是一个绝对指针,指向未发送但处在可发送范围内的第一个字节的序列号。
  • 发送方的可用窗口大小=SND.WND-(SND.NXT-SND.UNA)

3.2 接收方的滑动窗口

  • RCV.WND:表示接收创建大小,他会通告给发送方
  • RCV.NXT:是一个指针,它指向期望从发送方发送过来的下一数据字节的序列号。

3.3 操作系统缓冲区和滑动窗口的关系

  • 发送窗口和接收窗口中存放的字节数,都是存放在操作系统内存缓冲区中的。
  • 接收方的应用程序不能及时地读取缓冲区中的内容的话,则会影响接收方的滑动窗口的大小(RCV.WND)。
    • 假设缓冲区大小为200,刚开始接收方的滑动窗口大小则也是200
    • 发送方按序发送过来了100字节的数据,并且接收方也成功接收到了。但是此时接收方应用程序只能处理50字节的数据
    • 根据滑动窗口的原理可知RCV.NXT应该会向右移动100字节。但是还有50字节需要放在缓冲区中等待应用程序处理。因为缓冲区就那么大(200字节),所以此时RCV.WND的大小就变成了150。可用大小也是150.

  •  接收端通过TCP的Window字段告诉发送端自己还能接收150字节。则也会影响发送端的发送窗口大小。

3.4 什么是窗口关闭

  • TCP通过接收方指明希望从发送方接受的数据大小(窗口大小)来进行流量控制。
  • 如果窗口大小为0时,则会阻止发送方给接收方传递数据,直到窗口变为非0为止。这个过程就是窗口关闭。
  • 当接收方的接收窗口腾出来了,则就会发送一个ACK报文,将window字段设置为非0.

3.5 窗口关闭潜在的风险

  • 接收方向发送方告知窗口大小是通过ACK报文来通告的。
  • 如果发生了窗口关闭,接收方处理完数据后,会向发送方通告一个窗口非0的ACK报文告知发送方窗口大小已经变更。但如果这个通告窗口的ACK报文在网络上丢失,那么发送方的就一直不能发送数据。

3.6 如何解决窗口带来的潜在风险

  • 当发送方收到了零窗口通知,会启动一个持续计时器。

  • 当持续计时器超时后,发送方就会主动发送一个窗口探测报文。

  • 而接收方收到这个探测报文时,会给发送方回复一个确认,并给出自己现在的可接收窗口大小

    • 如果接收窗口仍然为0,那么收到这个报文的一方就会重新启动持续计时器

    • 如果接收窗口不是0,那么就可以发送数据了。

  • 窗口探测的次数一般是3次,每次大约30-60秒,超过3次还是0的话,有的TCP实现就会发RST报文来中断连接

3.7  如果接收方每次回应的窗口很小怎么办

  • 假设接收方回应的窗口过小,比如1字节。发送方该不该继续发?(TCP头部就20字节了)
  • 解决办法一:让接收方不告知小窗口
    • 如:当窗口大小<min(MSS,缓存空间/2)。就向发送方通知窗口为0。这样就阻止发送方再发数据过来。
  • 解决方法二:避免发送方在小窗口发送数据
    • 只有等到窗口大小>=MSS才发送数据

3.8 Nagle算法如何避免大量TCP小数据报文的传输?

  • Nagle算法的策略
    • 没有已发送未确认报文时,立刻发送数据
    • 存在未确认时,直到没有已发送未确认报文数据长度达到MSS大小时,再发送数据
    • 不满足上述条件的任意一条,发送方就一直囤积数据,直到满足条件位置
  • 所以这种方式不适合网络实时游戏,比如王者荣耀
  • 系统默认开启Nagle算法,只能通过Socket设置TCP_NODELAY选项来关闭这个算法(即无法全局关闭)

3.8 什么是流量控制

  • 接收方通过TCP的window字段去告知发送方自己的实际接收能力,然后发送方根据这个实际接收能力控制自己发送的数据量,这就是流量控制。
  • 流量控制是基于滑动窗口实现的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值