每次面试的时候都会被聊到这个话题,但每当要说时,就发现并不能侃侃而言。
按照自己的理解整理tcp拥塞控制一些知识,参考网络,做汇总笔记,如有不对,请指正~
tcp是流式,可靠的传输控制协议。
1:流式传输: 计算机数据的本质是0/1序列(文本流),tcp协议实现了端口到端口的通信,虚拟了文本流的通信。
但是,传输层的下一层是网络层,即ip层,会把数据打包发送,ip层的MTU长度限制,会使tcp协议将数据切割成片段,打包依次发送。
2:可靠传输:为了保证数据的可靠传输,tcp采用ack回复+重新发送机制保证(网络中丢包问题)
3:思考:ack和重新发送机制,必然影响到tcp的传输效率,tcp如何在传输可靠与传输效率上做控制的?
==》传输可靠:ack和重传机制
==》传输效率:拥塞控制(发送方)和流量控制(接收方)
拥塞控制:防止过多的数据注入网络,避免网络数据负载过大。(作用与发送方)(慢启动 拥塞避免 快重传 快恢复)
流量控制:告知发送方,接收方可以接收到的数据缓冲区大小,保证数据能完整接收到。(作用于接收方)
让发送端发送频率不那么快,保证接收端能来得及接收。
tcp协议中定义了一个16位的窗口大小(65535字节),描述了接收方接收窗口大小。
tcp的发送方发送窗口大小,不能大于接收端发回的窗口大小。(如果接收方窗口大小返回0,就停止发送,直到发送非零窗口大小(如果这个报文丢失会死锁?定时器解决,零窗口探测))
tcp流量控制是通过滑动窗口实现的:连续ARQ协议
回退N帧ARQ协议:
==》接收端丢弃第一个没接收到的数据包后面的所有包,
==》发送端收到NACK后,从NACK中指示的包
选择性重传ARQ协议:
==》发送端连续发送数据包但对每个数据包都设有个一个计时器
==》当在一定时间内没有收到某个数据包的ACK时,发送端只重新发送那个没有ACK的数据包。
发送方的拥塞窗口:一般就是我们所说的滑动窗口
接收窗口:tcp首部字段中的一个16bit的字段,描述当前套接字的接收窗口大小。
本质是描述接收方的tcp数据缓冲区大小,在tcp首部中含有一个16bit的字段,发送方会根据这个数据计算自己能发送的数据的长度。
如果接收方窗口大小为0,则发送方停止发送数据。
tcp拥塞窗口大小:采用慢启动和拥塞控制算法机制控制,参考下文。
这里有几个概念,一直很模糊:
接收窗口(RWND):tcp首部中一个16bit字段(可扩展),ack回复中会带该字段,描述了接收窗口大小,发送方发送数据要小于该值,达到限流。
拥塞窗口(CWND):发送方维护的一个窗口大小,是动态变化的,通过慢启动,拥塞避免控制方案。
发送窗口(swnd):取拥塞窗口和接收窗口中的较小值,一般和拥塞窗口 值大小一样。
慢启动门限(ssthresh):通过慢启动对阻塞窗口进行控制使,cwnd小于ssthresh时成倍数增长,大于ssthresh时加1控制,该值一开始限定,也是动态变化的。
最大报文段长度(MSS): tcp这里一般用MTU的值,其实要协商的,一般MSS值为1460,我们所描述的拥塞窗口大小,是以此为单位的。
总结:流量控制即,通过拥塞窗口和接收窗口,控制发送数据的大小。
拥塞控制作用于网络,防止过多的数据注入网络,造成网络负载过大(路由器缓冲区等可以造成网络阻塞)。
1:慢启动,拥塞避免
2:快重传,快恢复
拥塞窗口:发送方维持了一个动态变化的窗口,取决于网络的拥塞情况。
慢启动和拥塞避免算法(描述了网络的拥塞状况),主要控制了对拥塞窗口的限制。
在主机开始时,逐步探测网络状况,改变发送窗口的大小,加倍增长。
在慢启动的基础上,当发送窗口大于慢启动门限值时,使用该算法改变窗口大小。 加1
在改变发送窗口进行数据传输时,如果没有按时收到确认,可以认为时网络拥塞,这时候,把慢启动门限值降为当前拥塞窗口值得一半,重置拥塞窗口的大小为1,重新进行慢启动运算。
1:初始化时,拥塞窗口cwnd为1,慢启动门限定位为16
2:采用慢启动算法,实现数据得传输,如果没有发送网络拥塞,发送窗口以2的倍数增长(单位时MSS)(如果发送网络拥塞时,依次执行第5步)。
3:当下一次发送窗口(即拥塞窗口)的值大于慢启动门限值(ssthresh),改为拥塞避免算法,每次发送窗口+1
4:继续进行传输数据,发送窗口(拥塞窗口)值一直在变化,增大。
5:当发送窗口增大到出现网络拥塞时(没有按时收到ack),把慢启动门限值修改为当前拥塞窗口的1/2, 重置当前发送窗口为1,重新开始慢启动,依次第二步循环。 ===》即发生超时重传的场景
注意:这里在滑动窗口的基础上,有已经接收到对端回复,发送但没有接收到对端ack回复,待发送的数据等数据的维护,以及滑动窗口的移动。
快重传和快恢复时配合使用,一般发生快重传时,就会触发执行快恢复。
发送方只要连续收到三个重复确认的序号,会立即重发没有收到的报文。
tcp认为这种情况不严重,只丢失了一部分数据,进入快恢复算法:
1:改变拥塞窗口值为原来的一半(这里的拥塞窗口和发送窗口一样)
2:改变慢启动门限为拥塞窗口值(第一步计算后的),
3: 继续执行拥塞避免算法。
发送窗口,拥塞窗口,接收窗口
===》发送窗口 是拥塞窗口和接收窗口中的较小值,一般和拥塞窗口一致,因为接收窗口一般很大
我们通常所说的窗口大小,以MSS(最大报文段长度为单位)
流量控制: 通过接收窗口(tcp首部16bit的字段,可扩展)限制,使接收端能正常接收到数据(该值为0停止发送)。
拥塞控制(调整拥塞窗口,对发送数据进行控制,发送窗口动态变化的,慢启动门限也动态变化):
==》使用慢启动和拥塞避免算法,
==》快重传和快恢复算法
拥塞窗口的基础上,内部有已经发送,允许发送,还没有不允许发送,数据包的一个控制,延迟ack等的控制。
除此之外,tcp其他可靠性通过定时器实现:
==》建立连接定时器,重传定时器(RTO),坚持定时器(persist timer),延迟定时器(Delayed ACK),保活定时器(Keep Alive),FIN_WAIT_2定时器,TIME_WAIT定时器