TCP协议是可靠的协议,流量控制是考虑到接受端的限制,比如接受方缓冲区只有6000字节,那么发送端不能发送超过6000字节的报文,流量控制是接受端根据自身的情况而约束发送端的发送报文的速度和大小,流量控制使用的一个滑动窗口(rwnd),当TCP协议建立后接受端回复ACK报文中附加有滑动窗口,那么发送端不能发送超过滑动窗口的报文,当窗口大小为0时就表示接受端拒绝接受数据,发送端应该停止发送数据包。
1、滑动窗口
TCP三次握手建立连接中会把自己的起始序列号告诉对端,这个起始序列号不一定是从零开始的,是随机生成的一个数字。接收端收到数据包后会回复对端ACK和确认序列号,确认序列号是起始序列号+接受数据的字节+1,如下图假如已经TCP三次握手已经建立连接,接受端的序列号从0开始,接受窗口是500字节,窗口的单位是字节而不是数据包数,发送端第一次发送500字节,接受端第一个次回复ACK序列号201,窗口500,但还有301 - 501字节没有收到ACK确认,这时窗口向前滑动200字节,窗口范围变成301 - 701,因为还是300字节没有收到确认,所以发送端这次最多只能发送200字节的数据包,这是发送端再发送200字节。第二次接受端回复ACK,确认序列号是501,窗口是600,此时还是601 - 701这200个字节还没有收到确序列号,接受窗口扩大成600,此时滑动窗口应用向前推进400,滑动窗口范围变成601 - 1101。接受端不是接受1字节的数据包后解会发ACK+1序列号确认号,而是会积累ACK,比如积累到400个字节在回复ACK+序列号确认号。这样有利于提高传输效率。当接收端回复窗口为0时,发送端应该禁止发送数据。
![](https://i-blog.csdnimg.cn/blog_migrate/8664605664606ddab0a9b2c1fe849c53.png)
2、重传机制
1因为TCP是可靠的传输协议,重传机制是保证TCP数据的可靠送达。比如接受窗口大小是600字节,第一个次发送端发送了100字节,收到ACK+101序列号确认,窗口还剩600字节,这时发送端再发送200字节(201 - 301),这时还是收到ACK+101序列号的确认,应该窗口还有400字节,再发送200字节(401 - 501),此时还是收到ACK+101序列号确认,窗口大小还有200字节,在发送100字节(601),如果还是收到ACK+101序列号确认,窗口还剩100。共收到三次ACk + 101序列号确认,这说明201 - 601这一段的数据丢失了,此时应该从201处重传。
![](https://i-blog.csdnimg.cn/blog_migrate/7bb850e13fddd6cb85b485dc468e1370.png)
TCP每发送一个报文后就会给设置一个定时器,定时器的超时时间是1.5s,如果过了1.5s还没有收到ACK确认就认为这个数据包丢失了就会重传,重传后就会将定时器设置为3s,如果再超时继续重传,定时器的时间继续增大分别是1.5s、3s、6s、12s、24s、64s,当重传了5次达到64s还没有收到ACk就发送一个RST复位报文,关闭连接。
3、坚持定时器
当接受端的缓冲区大小为0是,就会发送ACK+窗口大小为0的报文给发送端,此时发送端不会在发送数据包直到收到接收端的ACK+窗口大小不为0。当接收端口的缓冲区有空间了,就会发送ACK+窗口大小给发送端,如果这个ACK在传输途中丢失了,发送端就会一直等待接受端发送的ACK + 窗口大小,而接受端一直在等待发送端的数据包,这样就进入互相等待的死锁状态。为了防止这种死锁等待,发送端在收到窗口为0后就会启动一个坚持定时器(persist timer)周期发送探测包以便直到窗口变大,刚开始定时为5s,然后一次增到5s、6s、12s、24s、48s、60s,定时器时间依次增大最大是60s,直到窗口被打开。