4-6:TCP协议之滑动窗口

Posted 快乐江湖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4-6:TCP协议之滑动窗口相关的知识,希望对你有一定的参考价值。


本文大部分内容来自小林coding《图解网络》,感谢分享,简单整理。

一:滑动窗口

在前面的讲解中,我们知道TCP是每发送一个数据都要进行依次确认应答,当上一个数据包收到ACK了,才会发送下一个,这种逻辑类似于我和你面对面聊天,我说一句你回一句,其实大家可以发现这种方式效率是十分低下的,放在TCP中也是如此,客户端和服务端数据交互量非常大,如果按照这种速度那显然不合理


所以采用这种方式的弊端很大:数据包往返的时间很长,通信效率极低

因此,为了解决这样的问题,TCP中引入了窗口这个概念,以保证即使在往返时间较长的情况下,也不会降低网络通信的效率。
有了窗口就可以指定窗口大小,所谓窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值

  • 窗口的实现实际上是操作系统开辟的一个缓存空间,发送刚主机在等到ACK返回之前,必须在缓冲区中保留已经发送的数据,如果按期收到ACK,那么数据就可以从缓冲区中清除

如下图,假设窗口大小为3个TCP端,那么发送方就可以连续发送3个TCP,并且途中若有ACK丢失,则可以通过下一个确认应答进行确认

  • 上图中的ACK600确认应答报文丢失也没有关系,因为可以通过下一个确认应答进行确认,只要发送方收到了ACK700确认应答,就意味着700之前的所有数据接收方都已经收到了。这个模式叫做累计确认或累计应答

前面说过TCP头部中有一个字段就是窗口大小

该字段是接受端告诉发送端自己还有多少缓冲区可以接受数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。
所以,通常窗口的大小是由接收方的窗口大小决定的,发送方发送的数据大小可以超过接收方的窗口大小,否则接收方就无法正常接收到数据

二:滑动窗口格式详解

(1)发送方的滑动窗口

如下是发送方缓存的数据,根据处理的情况可以分为四个部分。

  • #1是已经发送并收到ACK确认的数据
  • #2是已经发送但没有收到ACK确认的数据
  • #3是没有发送但总大小在接收方处理范围(接收方还有空间)的数据
  • #4上是没有发送但总大小超过接收方处理范围(接收方没有空间)的数据

如下图,如果发送方把数据全部一下子发出去之后,可用窗口就变为0了,表示可用窗口用尽,在没有收到ACK之前无法继续发送数据

接着,当收到之前发送的数据的ACK时,比如下面的32-36字节ACK之后,如果发送窗口大小没有变化,则滑动窗口右移5个字节,因为有5个字节已经被ACK。接着52-56字节就又成为了可用窗口,那么后序黄色范围的数据也就可以又发送了

上面只是宏观上面的描述,那么程序是如何描述这样的操作的呢?
实际上,TCP滑动窗口使用三个指针来跟踪在4个传输类别中的每一个类别的字节,其中两个指针是绝对指针(指特定的序列号),一个是相对指针(需要做偏移)

  • SND.WND:表示发送窗口的大小(由接收方指定)
  • SND.UNA:是一个绝对指针,指向已发送但没有收到确认的第一个字节的序列号
  • SND.NXT:是一个绝对指针,指向没有发送但在可发送范围内的第一个字节的序列号
  • 指向#4的是一个相对指针它需要SND.UNA指针加上SUND.WND大小的偏移量

因此可用窗口大小=SND.WND-(SND.NXT-SND.UNA)

(2)接受方滑动窗口

如下是接收方滑动窗口格式,相对发送方要简单一些

  • #1,#2是已成功接收并确认的数据(等待应用层读取)
  • #3是没有收到但可以接受的数据
  • #4是没有收到但不可以接受的数据

这几个部分由如下指针指向

  • RCV.WND:表示接收窗口大小,它会告知给发送方
  • RCV.NXT:是一个指针,它指向期望从发送方接受来的下一个数据字节的序列号,也就是#3的第一个字节
  • 指向#4的第一个字节是一个相对指针,需要RCV.NXT指针加上RCV.WND大小的偏移量

以上是关于4-6:TCP协议之滑动窗口的主要内容,如果未能解决你的问题,请参考以下文章

一篇带你读懂TCP之“滑动窗口”协议

一篇带你读懂TCP之“滑动窗口”协议

计算机网络之TCP协议流量拥塞控制算法原理:滑动窗口cwnd与rwnd

校招面试 之 网络第2题 TCP的可靠传输流量控制滑动窗口

tcp窗口滑动以及拥塞控制

tcp滑动窗口与拥塞控制