传输层-第三节1-4:TCP流量控制
Posted 快乐江湖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了传输层-第三节1-4:TCP流量控制相关的知识,希望对你有一定的参考价值。
- 本文大部分内容来自博主:【小林coding】,如有需求请大家关注。本文会在此基础上结合王道课本进行梳理
文章目录
一:流量控制
- 发送方不能无脑给接收方发送数据,否则接收方由于无法及时接收,就会触发重传,从而引起资源浪费
流量控制:为了解决这一问题,TCP提供了一种机制可以让发送方根据接收方实际接受能力控制发送的数据量
如下图是一个经典的场景,其中
- 客户端是接收方,服务端是发送方
- 假设接受窗口和发送窗口都为200
- 假设两个设备在传输过程中都保持相同的窗口大小,不受外界影响
过程解释如下
- 1:客户端向服务端发送请求数据报文
- 2:服务端受到请求报文后,发送确认报文和80字节的数据,于是可用窗口可用窗口减少为120字节。同时,
SND.NXT
指针也向右移动80字节,指向321,意味着下次发送数据序列号为321 - 3:客户端收到80字节数据后,其接受窗口向右移动80字节,
RCV.NXT
指向321,意味着客户端期望的下一个报文序列号是321,接着发送确认报文给服务端 - 4:服务端再次发送120字节数据,可用窗口耗尽为0,无法再发送数据
- 5:客户端收到120字节数据后,接受窗口向右移动120字节,
RCV.NXT
指向441,接着发送ACK - 6:服务端收到对80字节数据的确认报文后,
SUD.UNA
指针向右偏移指向321,于是可用窗口增大到80 - 7:服务端受到对120字节的确认报文后,
SUD.UNA
指针向右偏移指向441,于是可用窗口增大到200 - 8:服务端现在可以继续发送,发送160个字节的数据后,
SND.NXT
指向601,可用窗口减少到40 - 9:客户端收到160字节后,接收窗口向右移动160字节,
RCV.NXT
指向601,接着发送ACK - 10:服务端收到对160字节数据的确认报文后,发送窗口向右面移动60字节,
SND.UNA
指针偏移160后指向601,可用窗口增大至200
二:操作系统缓冲区与滑动窗口的关系
上面的例子中,发送窗口和接受窗口的大小是不变的。但在实际情况中,发送窗口和接受窗口中存放的字节数,都会存放在操作系统中的内存缓冲区,因此一定会受到操作系统的控制而被调整。当应用程序由于各种原因未及时读取缓冲区中的内容时,也会对缓冲区造成影响
(1)若应用程序没有及时读取缓冲区
下面的例子展示的是由于应用程序没有及时读取缓冲区时,发送窗口和接受窗口的变化情况,其中
- 客户端为发送方,服务端为接收方,发送窗口和额接受窗口初始大小为360
- 服务端很忙,收到客户端数据时,应用层未能及时处理数据
过程如下
- 1:客户端发送140字节数据,可用窗口变为220
- 2:服务端受到140字节数据,由于服务器繁忙,应用程序仅仅读取了40字节,还有100字节占用缓冲区,因此接收窗口缩小到260(360-100),最后发送ACK时,将窗口大小告知客户端
- 3:客户端收到ACK后,将发送窗口减少为260
- 4:客户端发送180字节数据,可用窗口减少到80
- 5:服务端收到180字节后,但是应用层没有读取任何数据,180字节直接留在了缓冲区,于是接收窗口缩小到了80(260-180),最后发送ACK时,将窗口大小告知客户端
- 6:客户端收到ACK后,将发送窗口减少为80
- 7:客户端发送80字节数据后,可用窗口耗尽
- 8:服务端收到80字节数据,但是应用程序依然没有读取任何数据,这80字节仍然留在缓冲区,于是接收窗口缩小到了0,最后发送ACK时,将窗口大小告知客户端
- 9:客户端收到ACK后,将发送窗口减少为0
最后窗口变为了0,也即是发生了窗口关闭。当发送方窗口为0时,发送方实际上会定时发送窗口探测报文,以便知道接受方的窗口是否发生了改变。
(2)操作系统直接减少缓冲区大小
当服务器系统资源很紧张的时候,操作系统可能会直接减少接受缓冲区的大小,这时应用程序又无法及时读取缓冲区数据的话,那么可能导致丢包现象的产生
如下图是一个经典的例子
- 1:客户端发送140字节的数据,可用窗口减少到了220
- 2:服务端因为现在非常繁忙,操作系统于是就把接受缓存减少了120字节,当收到140字节数据后,由因为应用程序没有及时读取数据,所以140字节留在了缓冲区中,于是接受窗口大小由360缩小到了100。最后发送ACK时,通知窗口大小给对方
- 3:此时客户端因为还没有收到服务端的ACK,所以不知道此时接受窗口缩减到了100,客户端只会看到自己的可用窗口还有220,于是客户端发送了180字节数据,可用窗口减少到了40
- 4:服务端收到了140字节数据,发现数据大小超过了接收窗口的大小,于是直接把数据丢了
- 5:客户端收到第2步服务端发送的ACK后,尝试减少发送窗口到100,把窗口的右端向左收缩了80,但是在第3步时,已经发送了超过100字节的数据,所以可用窗口出现负值
所以如果发生了先减少缓存,再收缩窗口,就会出现丢包的现象。因此为了防止这种情况发生,TCP规定不允许同时减少缓存又收缩窗口的,而是先收缩窗口,一定时间后再减少缓存
以上是关于传输层-第三节1-4:TCP流量控制的主要内容,如果未能解决你的问题,请参考以下文章