目录
1.Tcp流量控制
2.滑动窗口
2.1滑动窗口的更新
2.2滑动窗口的丢包问题
1.报文丢失的情况
2.ACK丢失的情况
3.拥塞控制
3.1慢启动
3.2拥塞窗口的增长
1.Tcp流量控制
为什会有流量控制?
1.在网络通信中,假如发送方的发送能力特别的强,接受方的接受缓冲区都满了,发送方还在继续发,这些多余的报文就会被丢弃,这就造成了网络资源的浪费。
2.接受方的接受能力特别强,接受方的接受缓冲区,一直是空的,接收方都快饿死了,
所以接收方需要告知发送方自己的接受能力。
当接受方对发送方进行 ACK时,Tcp报头中是有一个16位窗口大小的,16位窗口大小就是接受缓冲区剩余的大小,当接受缓冲区满了,16位窗口大小就为0。
2.滑动窗口
在tcp在发送消息的时候,不是一条一条的发送的,这样数据往返时间太长了,效率太低了。
Tcp会一口气发送多条消息,在一起收到多条应答。
那这时候就会有个问题,到底一次发送多少消息合适呢?
在tcp缓冲区中存在一个窗口,在这个窗口内的数据,不用收到任何ACK,直接就可以发送给对方。
滑动窗口本质就是 两个数组的下标,一个指向窗口的开始,一个指向窗口的结束。
int win_begin = 2001 , int win_end = 6001。
2.1滑动窗口的更新
滑动窗口的大小是根据ACK应答中的16位窗口大小和确认序号,实时更新的。
确认序号就是下次该发送数据的下标。
例:收到的ACK确认序号是3001,16位窗口大小是 5000,那么滑动窗口该如何更新呢?
win_begin = 确认序号, win_end = 确认序号 + 16位窗口大小。(暂时这样认为)
2.2滑动窗口的丢包问题
1.报文丢失的情况
例:1001 - 2001 这个报文丢失
1001 - 2001 这个报文丢失所以1001 - 2001 这段报文是没有返回ACK的,根据确认序号的定义,确认序号保证确认序号之前的数据已经被收到,因为1001丢失,所以剩下所有报文ACK的确认序号都是1001,因为只有1001之前的所有数据被主机B收到了。
这里不得不提到Tcp的快重传机制
连续3个ACK确认序号都是相同的时候,这时候需要迅速对其进行补发,不用等待超时重传。
当主机B收到1001-2001的这个数据时候,7001之前的所有数据都被收到了,补发报文ACK的确认序号不就是7001吗。
2.ACK丢失的情况
先说结论:少量的ACK丢失并不影响正常的通信。
一切原因都是因为确认序号的定义,因为确认序号之前的数据全都被收到了。
1001的ACK丢失了,但是主机A2001的ACK收到了,这个ACK的确认序号是2001,这代表着2001之前的所有数据主机B已经收到了,虽然1001的ACK丢失了,但是并不妨碍主机A知道1-1000的数据主机B已经收到了。
3.拥塞控制
Tcp虽然拥有的滑动窗口这个大杀器,可以有效的提高数据发送的效率,但是滑动窗口只是限定双方主机,并没有考虑网络,假如现在的网络已经很拥堵了,还向网络中发送大量的数据,数据不仅发送不出去,还会加重网络的拥堵,所以就有了网络的拥塞控制。
3.1慢启动
慢启动就是先向网络中发送少量的信息,探测一下当前网络的拥塞状态,如果网络通畅在发送大量的数据。
这里引入拥塞窗口的概念,拥塞窗口告诉当前主机网络的拥塞状态,拥塞窗口越大,能发送的数据越大。
拥塞窗口一开始的值为1.
在这里重谈一下,滑动窗口大小的计算。
int win_begin = 确认序号, int win_end = 确认序号 + min(拥塞窗口大小,16位窗口大小);
3.2拥塞窗口的增长
1.ssthresh是造成网络拥堵窗口大小的一半。
2.在到达ssthresh之前拥塞窗口是指数级增长。
3.ssthresh之后是线性增涨的直到发生网络拥塞,拥塞窗口的值变为1.