深入理解TCP协议之拥塞控制

912 阅读4分钟

深入理解TCP协议之拥塞控制

本文正在参与 “网络协议必知必会”征文活动

什么是TCP的拥塞控制

TCP拥塞控制是针对于发送端的;网络拥塞简单来说,是指在一段时间内,客户端请求的数量突然陡增(多对一),导致服务端对巨量的请求无法处理数据并正常发送出相应数据的场景。
举个栗子:

  • 大家中午刚下班的食堂,对于"饥肠辘辘"排队的干饭人,老板看着这么多人心里不禁乐开了花,但是一个人分身乏力,难以短时间满足这么多人的就餐需求,这个就是网络拥塞\color{FF0000}网络拥塞
  • 但是老板因为抠门没有布置出单机器,因为人太多忘记做你的那一份,你不得不再次提醒老板你要的是黄焖鸡,这个就是数据重传\color{FF0000}数据重传
  • 排队的人越来越多,老板手忙脚乱,可能忘记做的饭越来越多,大家不得不都需要重新给老板再次报一次,点餐等待的人群和新加入队伍的人越来越多,浪费了大家中午本就不多的午休时间,这个就叫网络拥塞的恶性循环\color{FF0000}网络拥塞的恶性循环

网络拥塞的解决办法:拥塞控制

上面我们讲到了,如果没有相应的规则来约束,会很容易造成客户端请求不到对应数据,服务端也无法正常发送相应数据的情况。所以拥塞控制机制就出现了。了解它之前,我们应该先简单了解几个知识来方便我们理解如何控制网络拥塞。(为了方便理解,我们暂时把请求数据传输的一端称为客户端,发送数据的一端称为服务端。)

  • 拥塞窗口(cwnd) 指服务端未收到客户端的ACK值(服务端:黄焖鸡好啦~,客户端:来了来了这个回应就是返回的ACK)之前,还能发送的数据量大小。这个值只在服务端本地维护并使用,并不在报文中体现。

  • 接收窗口(rwnd) 指客户端的接收数据的缓存剩余空间的最大值。

  • MSS(MSS Max Segment Size)最大分段大小 TCP传输的过程中,数据并非是单独传输的,而是被通过数据流的形式分片传输的(5000字节的数据可能会分三次,也可能会分五次传输),而MSS则是规定在一次TCP报文中,传输的数据最大值。在以太网中 TCP的MSS = 1500(MTU) - 20(IP头大小) - 20(TCP头大小) = 1460(允许的最大字段大小)。有时也会因为TCP头中的options选项占用[-12(TCP OPTIONS大小)]减小MSS的值。

  • RTT(Round Trip Time) 往返时间 指服务端发送第一个数据包给客户端开始到接收到确认信号(客户端返回ACK)经历的时间。

  • ssthresh(Slow Start Threshold) 慢启动阈值 为了控制cwnd无限制增大,保证以一个可控的状态而设置的值,下方慢启动章节会详细讲解。

真正的发送窗口大小最终取决于拥塞窗口、接收窗口两者间的最小值。(老板:来一大份吧;我:不了不了,我要一小份就行~)

慢启动(Slow Start)

好了,我们说回正经的。在建立连接前,服务端如何确定发送多少数据给客户端才合适?给小了增加连接次数,给大了容易造成延迟和丢包。所以在TCP连接之初,服务端会自定一个initcwndinitcwnd的东西,初始值一般为10。每次发送数据确认后,如果客户端没有丢包的情况,就默认客户端接收良好,就会增加cwnd的大小。具体计算方式是:

  • 每收到客户端一次ACK回复,cwnd = cwnd +1
  • 在每经过一个RTT(往返时间),cwnd = cwnd * 2 这样,在短时间内会以指数级提升。这样设计的的方式既保证了传输前期数据传输的稳定性,也保证了在网络通畅的情况下,能够快速响应请求,保证了时效性。但cwnd不能无休止的通过传输来进行自增长,最终会走向失控。为了保证cwnd能在一个符合客户端/服务端大小的值,设计了 ssthresh 值。当cwnd < ssthresh时,处在慢启动阶段,传输途中进行快速提升;当cwnd = ssthresh时,就进入到了拥塞避免(按线性增长)中。

拥塞避免(Congestion Avoidance)

拥塞避免的计算方式则保守的多,触发方式为:当cwnd > ssthresh 时,更换计算cwnd的计算方式,计算方式为:

  • 在每经过一个RTT(往返时间),cwnd才加一。cwnd = cwnd + 1 这样的计算方式,即保证了在网络良好的情况下也能有一定增长,也保证了cwnd以一个双方近乎最佳的值进行传输。

以上就是TCP协议之拥塞控制的全部内容了,个人理解,如果有错误或偏差,也希望大家多多指出斧正,感谢大家花时间读到这里。