TCP如何利用滑动窗口实现流量控制
前言:
- 为什么需要流量控制 因为如果发送方把数据发送的过快,接收方就可能来不及接收,这就会造成数据的丢失
流量控制
就是让发送方的发送速率不要太快,让接收方来得及接收所有数据- TCP中是通过
滑动窗口机制
在TCP连接上实现对发送方的流量控制(接收方控制发送方)
流量控制的具体细节:
-
假设先不考虑
拥塞控制
,发送方的发送窗口
等于接收方的接收窗口
-
假设一个如下的TCP连接情况:
-
主机A和主机B已建立TCP连接,主机A给主机B发送数据,主机B对主机A进行流量控制;
-
为了叙述简单,假设主机A缓冲区的数据会按照
一个包100字节
的块发送,如下所示:
-
-
1、若在最开始的时候,主机B告诉主机A自己的
接收窗口
为400,那么主机A将自己的发送窗口设置为400; -
2、主机A发送
1~100号
的数据,主机A发送101~200号
数据,主机A继续发送201~300号
数据,理论上可以一直将发送窗口
内的数据全部发完 -
3、若主机A发送的
1~100号
、101~200号
数据顺利到达主机B并被主机B接收, 但是201~300号
意外丢失了。主机B会返回响应ACK=1,ack=201,rwnd=300
,这表示主机B已接收到201号之前的数据,(假设)并将自己的接收窗口
设置为300- (这是主机B对主机A的一次流量控制,因为其缩小了自己的接收窗口)
-
4、主机A接收到主机B发来的响应后
- 因为知道了201号之前的数据已被成功接收,所以会将
发送窗口
向前滑动,将201号之前的数据移出发送窗口,同时可以销毁缓冲区内201号之前的数据。 - 又因为主机B的接收窗口调整为300,所以主机A将自己的发送窗口也调整为300,此时发送窗口内数据的序号为
201~300
、301~400
、401~500
- 因为知道了201号之前的数据已被成功接收,所以会将
-
5、主机A继续发送
301~400
、401~500
也即发送窗口内的数据;发送窗口内的数据发送完后发送方暂停发送。 -
6、主机A每次发送TCP报文段都会开启一个
重传计时器
,假设现在201~300号
数据对应的重传计时器超时了,主机A会再次将该段数据包装好并发送去seq=201,data...
-
7、若主机B接收到
201~300号
数据,将返回响应ACK=1,ack=501,rwnd=100
,表示主机B已成功接收501号之前的数据,并假设将自己的接收窗口设置为100- (这是主机B对主机A的又一次流量控制,因为其缩小了自己的接收窗口)
-
8、主机A接收到主机B发来的响应后,与第4步类似
- 因为知道了501号之前的数据已被成功接收,所以会将
发送窗口
向前滑动,将501号之前的数据移出发送窗口,同时可以销毁缓冲区内501号之前的数据 - 又因为主机B接收窗口调整为100,所以主机A将自己的发送窗口也调整为100,此时主机A发送窗口内的数据序号为
501~600号
- 因为知道了501号之前的数据已被成功接收,所以会将
-
9、主机A继续发送其发送窗口内的
501~600号
数据,发送窗口内的数据全部发送完,所以暂停发送数据 -
10、主机B接收到
501~600号
数据,将返回ACK=1,ack=601,rwnd=0
进行累计确认,表示主机B已成功接收600号以前的数据,这里再次假设调整了自己的接收窗口为0- (这是主机B对主机A的又一次流量控制,因为其又改变了自己的接收窗口)
-
11、主机A接收到主机B的响应后,类似第4、第8步
发送窗口
向前滑动,将600号之前的数据移出发送窗口
,销毁缓冲区内600号之前的数据- 调整发送窗口大小为0
-
12、此时主机A的发送窗口为0,不能再发送普通的TCP数据报,并等待主机B发送改变其
接收窗口
的指令 -
13、若主机B的接收缓存腾出了一些存储空间,将接收窗口调整为300,并通告主机A
rwnd=300
,但是该数据包意外丢失了 -
14、主机A一直等不到主机B发送的调整其接收窗口的数据包,此时如果不采取措施就会陷入
死锁
,也即主机A等待B,主机B等待A。TCP流量控制中采取的解决方法如下:- TCP为每一个连接设置一个
持续计时器
,只要TCP的一方收到对方的零窗口通知,就启动该持续计时器
- TCP为每一个连接设置一个
-
15、直到
持续计时器
超时,主机A主动发送一个零窗口探测报文段
,该报文仅有1字节;主机B接收到该探测报文后立刻告知主机A自己的发送窗口
大小- 如果主机B的
接收窗口
还是0,主机A再重新开启一个持续计时器,然后等待持续计时器
超时 - 如果主机B的
接收窗口
不是0,上述的死锁局面就解决了
- 如果主机B的
问题1:在主机B接收窗口为0时还怎么接收主机A的0窗口探测报文段
呢?不是接收窗口已经为0了吗?
答:TCP规定,就算接收窗口为0,也必须接受零窗口探测报文段
、确认报文段
、以及携带有紧急数据的报文段
问题2:如果零窗口探测报文段
也丢失了怎么办?
答:零窗口探测报文段
也有设置的有重传计时器
,如果丢失,等待该计时器超时,然后重传零窗口探测报文段
总结起来就是:
-
发送方解析接收方的响应数据包,根据接收方的
接收窗口
大小调整自己的发送窗口
大小; -
发送方通过向前滑动发送窗口的方式移除已确认被正确接收的数据,并将他们从缓冲区删除;
-
发送方只发送自己发送窗口内的数据
-
发送窗口向前滑动的前提是发送窗口的数据确认被正确接收
这是学习湖科大计网时我做的学习笔记,老师讲的太好了,建议去看原版,B站就有!!!