zoukankan      html  css  js  c++  java
  • TCP-拥塞控制

     拥塞控制

    为什么要有拥塞控制?不是有流量控制了吗?

    前面的流量控制是避免【发送方】的数据填满【接收方】的缓存,但是并不知道网路中发生了什么。

    一般来说,计算机网络都处于一个共享的环境。因此也有可能会因为其他主机之间的通信使得网络拥堵。

    在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包延时、丢失等,这时TCP就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延时以及更多的丢包,这个情况就会进入恶性循环被不断地放大...

    所以,TCP不能忽略网络上发生的事,它被设计成一个无私的协议,当网络发生拥堵时,TCP会自我牺牲,降低发送的数据量。

    于是,就有了拥塞控制,控制的目的是避免【发送方】的数据填满整个网络 。

    为了在【发送方】调节所要发送数据的量,定义了一个叫做【拥塞窗口】的概念。

    什么是拥塞窗口?和发送窗口有什么关系?

    拥塞窗口 cwnd 是发送方维护的一个的状态变量,它会根据网络的拥塞程度动态变化的。

    我们在前面提到过发送窗口 swnd 和接收窗口 rwnd 是约等于的关系,那么由于引入了拥塞窗口的概念后,此时发送窗口的值是 swnd = min (cwnd , rwnd),也就是拥塞窗口和接收窗口中的最小值。

    拥塞窗口cwnd变化的规则:

    • 只要网络中没有出现拥塞,cwnd就会增大;
    • 但网络中m出现了拥塞,cwnd就减少;

    那么怎么知道当前网络中是否出现了拥塞呢?

    其实只要【发送方】没有在规定时间内接收到 ACK 应答报文,也就是发生了超时重传,就会认为网络出现了拥塞。

    拥塞控制算法:

    • 慢启动
    • 拥塞避免
    • 拥塞发生
    • 快速恢复

    慢启动

    TCP在刚建立连接完成后,首先有一个慢启动的过程,这个慢启动的意思j就是一点一点的提高发送数据包的数据量,如果一上来就发送大量的数据,这不是给网络添堵吗?

    慢启动的算法记住一个规则就行:当发送方每收到一个ACK,拥塞窗口cwnd 的大小就会加1。慢启动呈指数型增长。

    慢启动门限ssthresh(slow start threshold)状态变量:

    • 当 cwnd < ssthresh 时,使用慢启动算法
    • 当 cwnd >= ssthresh 时,就会使用拥塞避免算法

    拥塞避免

    前面说到,当拥塞窗口 cwnd 超过 慢启动门限 ssthresh 就会进入拥塞避免算法。

    一般来说, ssthresh 的大小是 65535 字节。那么进入拥塞避免算法后,它的规则是:每当收到一个 ACK, cwnd就增加 1/cwnd。呈线性增长。

    所以,我们可以发现,拥塞避免算法就是将原本的慢启动算法的指数增长变成了线性增长,还是增长阶段,只是增长速度缓慢了一些。

    就这么一直增长下去,网络就会慢慢进入拥塞的状况了,于是就会出现丢包现象,这时就需要对丢失的数据包进行重传。

    当触发重传机制,也就进入了【拥塞发生算法】

    拥塞发生

    当网络出现拥塞,也就是会发生数据包重传,重传机制主要有两种:

    • 超时重传
    • 快速重传

    发生超时重传的拥塞发生算法:

    • ssthresh 设为 cwnd / 2
    • cwnd 重置为 1

    发生快速重传的拥塞发生算法:

    TCP认为这种情况不严重,因为大部分没丢,只丢了一小部分,则 ssthresh 和 cwnd变化如下:

    • cwnd = cwnd / 2,也就是设置为原来的一半
    • ssthresh = cwnd;
    • 进入快速回复算法

    快速恢复

    快速重传和快速恢复算法一般同时使用,快速恢复算法认为,你还能接收到3个重复的ACK,说明网络也不是那么糟糕,所以没有必要像 RTO 超时那样强烈。

    正如之前所说,进入快速恢复之前,cwnd 和 ssthresh 已经被更新了,然后进入快速恢复算法如下:

    • 拥塞窗口 cwnd = ssthresh + 3 (3的意思就是确认已经有3个数据包被收到了)
    • 重传丢失的数据包
    • 如果再收到重复的ACK,那么cwnd增加1
    • 如果收到新数据的ACK后,设置 cwnd 为ssthresh,接着就进入拥塞避免算法
  • 相关阅读:
    修改FileUpload样式
    ASP.NET 中JSON 的序列化和反序列化
    C# 2.0中泛型编程初级入门
    50条经典爱情观
    (转贴)追MM与Java的23种设计模式
    猴子和香蕉的故事
    35岁前成功的12条黄金法则
    几个小故事
    java与C++的虚函数比较
    flask 源码解析:上下文(一) SUNNEVER
  • 原文地址:https://www.cnblogs.com/turbosha/p/13200703.html
Copyright © 2011-2022 走看看