前言:
好久没更新了,一直堆在笔记本里面,堆了有两三篇博客了,一直懒得更新,今晚逼着自己更新=。= 新的写法:摒弃了之前照抄书本的冗余文字,大多数以自己的话来口述过程。虽然可能会不准确,但看起来更像是自己的东西哈哈。
何为拥塞
客户端发送数据太多,发送太快导致网络中间层无法处理。表现:分组丢包、分组延迟大
拥塞控制的方法
- 端到端拥塞控制
端对端:ip层(网络层)不反馈拥塞信息,只能通过端对端来控制,tcp通过超时事件或者三次冗余的ack报文来判断拥塞 - 网络辅助拥塞控制
网络辅助:网络层的路由器向发送方提供显式的反馈信息。
TCP拥塞控制
tcp主要采用的是端对端拥塞控制,原因是ip层不反馈拥塞信息。
书中的内容主要分为一下三个问题。
如何控制?
通过控制拥塞窗口(cwnd)大小,即一次发送多少个数据报。
如何感知?
服务端接收3个冗余的ack报文、超时事件
何种算法改变?
tcp拥塞控制算法:慢启动、拥塞避免、快速恢复。
tcp拥塞控制算法
慢启动
[MSS->报文段里应用数据的最大值,未包含tcp报文段和ip数据报的首部,经典值为1460]
[MTU->链路层中能够承受的最大数据量叫做最大传输单元 经典值为1500]
-
初始化状态:cwnd的值为一个MSS大小 ,即初始化状态只能发送一个tcp报文
-
未到检测到拥塞:没收到一个ack确认报文,cwnd就加上一个MSS的值,所以cwnd以倍数形式增加 1-2-4-8-。。。。
-
检测到拥塞: 存在两种情况(1)超时指示的丢包 (2)三个冗余ack报文
两种情况的处理方式不同:
(1)超时指示的丢包:ssthresh(慢启动阈值)设置为cwnd的一半,然后把cwnd设置为一个MSS的大小,重新开始慢启动,此时的慢启动当cwnd>=ssthresh的时候进入拥塞避免
(2)三个冗余ack报文:ssthresh(慢启动阈值)设置为cwnd的一半,cwnd设置为ssthresh(慢启动阈值)的大小再加上3个MSS(用于重传3个冗余的ack报文对应的数据报----快速重传),然后进入快速恢复
拥塞避免
[RTT->一个报文到达客户端然后返回ACK报文,服务端接收到ACK报文所需的时间,简称往回时延]
进入拥塞避免状态的tcp连接,说明此时的cwnd的值是上一次拥塞时的一半,所以此时cwnd的增长会比较的保守。
每收到一个ACK报文就会增加(MSS/cwnd)*MSS个字节。即加入MSS为1460,cwnd此时是14600,那么在一个RTT内发送了10个报文段,每个到达ACK增加十分之一个MSS,则在收到10个ACK报文才增长了1个MSS。
然后一直增加++++++直到检测到拥塞:1)超时指示的丢包 (2)三个冗余ack报文
似曾相识:
(1)超时指示的丢包:ssthresh(慢启动阈值)设置为cwnd的一半,然后把cwnd设置为一个MSS的大小,重新开始慢启动,此时的慢启动当cwnd>=ssthresh的时候进入拥塞避免
(2)三个冗余ack报文:ssthresh(慢启动阈值)设置为cwnd的一半,cwnd设置为ssthresh(慢启动阈值)的大小再加上3个MSS(用于重传3个冗余的ack报文对应的数据报----快速重传),然后进入快速恢复
快速恢复
在快速恢复中对于引起tcp进入快速恢复的缺失报文,对每一个冗余的ack报文,cwnd增加一个MSS,即3个。即一开始的状态就是cwnd/2+3MSS
- 设置cwnd = ssthresh+ACK个数*MSS(一般情况下会是3个dup ACK)
- 重传丢失的数据包(对于重传丢失的那个数据包)
- 如果只收到Dup ACK,那么cwnd = cwnd + 1个MSS
- 如果收到新的ACK, 设置cwnd = ssthresh, 是因为该ACK确认了新的数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态。