拥塞控制 你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了( 四 )

拥塞控制 你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了


文章图片
可用窗口耗尽在下图,当收到之前发送的数据 32~36 字节的 ACK 确认应答后,如果发送窗口的大小没有变化,则滑动窗口往右边移动 5 个字节,因为有 5 个字节的数据被应答确认,接下来 52~56 字节又变成了可用窗口,那么后续也就可以发送 52~56 这 5 个字节的数据了。

拥塞控制 你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了


文章图片
32 ~ 36 字节已确认程序是如何表示发送方的四个部分的呢?
TCP 滑动窗口方案使用三个指针来跟踪在四个传输类别中的每一个类别中的字节。其中两个指针是绝对指针,一个是相对指针。

拥塞控制 你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了


文章图片
SND.WND、SND.UN、SND.NXTSND.WND:表示发送窗口的大小;SND.UNA:是一个绝对指针,它指向的是已发送但未收到确认的第一个字节的序列号,也就是 #2 的第一个字节。SND.NXT:也是一个绝对指针,它指向未发送但可发送范围的第一个字节的序列号,也就是 #3 的第一个字节。指向 #4 的第一个字节是个相对指针,它需要 SND.UNA 指针加上 SND.WND 大小的偏移量,就可以指向 #4 的第一个字节了。那么可用窗口大小的计算就可以是:可用窗口大 = SND.WND -接收方的滑动窗口
接下来我们看看接收方的窗口,接收窗口相对简单一些,根据处理的情况划分成三个部分:#1 + #2 是已成功接收并确认的数据;#3 是未收到数据但可以接收的数据;#4 未收到数据并不可以接收的数据;

拥塞控制 你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了


文章图片
接收窗口RCV.WND:表示接收窗口的大小,它会通告给发送方。RCV.NXT:是一个指针,它指向期望从发送方发送来的下一个数据字节的序列号,也就是 #3 的第一个字节。指向 #4 的第一个字节是个相对指针,它需要 RCV.NXT 指针加上 RCV.WND 大小的偏移量,就可以指向 #4 的第一个字节了。接收窗口和发送窗口的大小是相等的吗?
并不是完全相等,接收窗口的大小是约等于发送窗口的大小的。因为滑动窗口并不是一成不变的。比如,当接收方的应用进程读取数据的速度非常快的话,这样的话接收窗口可以很快的就空缺出来。那么新的接收窗口大小,是通过 TCP 报文中的 Windows 字段来告诉发送方。那么这个传输过程是存在时延的,所以接收窗口和发送窗口是约等于的关系。流量控制发送方不能无脑的发数据给接收方,要考虑接收方处理能力。如果一直无脑的发数据给对方,但对方处理不过来,那么就会导致触发重发机制,从而导致网络流量的无端的浪费。为了解决这种现象发生,TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制。下面举个栗子,为了简单起见,假设以下场景:

拥塞控制 你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了


文章图片
流量控制根据上图的流量控制,说明下每个过程:客户端向服务端发送请求数据报文。这里要说明下,本次例子是把服务端作为发送方,所以没有画出服务端的接收窗口。服务端收到请求报文后,发送确认报文和 80 字节的数据,于是可用窗口 Usable 减少为 120 字节,同时 SND.NXT 指针也向右偏移 80 字节后,指向 321,这意味着下次发送数据的时候,序列号是 321。客户端收到 80 字节数据后,于是接收窗口往右移动 80 字节,RCV.NXT 也就指向 321,这意味着客户端期望的下一个报文的序列号是 321,接着发送确认报文给服务端。服务端再次发送了 120 字节数据,于是可用窗口耗尽为 0,服务端无法在继续发送数据。客户端收到 120 字节的数据后,于是接收窗口往右移动 120 字节,RCV.NXT 也就指向 441,接着发送确认报文给服务端。服务端收到对 80 字节数据的确认报文后,SND.UNA 指针往右偏移后指向 321,于是可用窗口 Usable 增大到 80。服务端收到对 120 字节数据的确认报文后,SND.UNA 指针往右偏移后指向 441,于是可用窗口 Usable 增大到 200。服务端可以继续发送了,于是发送了 160 字节的数据后,SND.NXT 指向 601,于是可用窗口 Usable 减少到 40。客户端收到 160 字节后,接收窗口往右移动了 160 字节,RCV.NXT 也就是指向了 601,接着发送确认报文给服务端。服务端收到对 160 字节数据的确认报文后,发送窗口往右移动了 160 字节,于是 SND.UNA 指针偏移了 160 后指向 601,可用窗口 Usable 也就增大至了 200。操作系统缓冲区与滑动窗口的关系前面的流量控制例子,我们假定了发送窗口和接收窗口是不变的,但是实际上,发送窗口和接收窗口中所存放的字节数,都是放在操作系统内存缓冲区中的,而操作系统的缓冲区,会被操作系统调整。当应用进程没办法及时读取缓冲区的内容时,也会对我们的缓冲区造成影响。那操心系统的缓冲区,是如何影响发送窗口和接收窗口的呢?

推荐阅读