计算机 · 2021年7月16日 0

TCP

https://zhuanlan.zhihu.com/p/388704023

拥塞控制

慢启动,拥塞避免,快速重传,快速恢复

慢启动算法:

  • TCP连接完成,初始化cwnd = 1,表明可以传一个MSS单位大小的数据;
  • 每当收到一个ACK,cwnd就加一;
  • 每当过了一个RTT,cwnd就增加一倍; 呈指数上升;
  • 慢启动门限(slow start threshold, ssthress)
    TCP初始化为65535个字节,这个是TCP设计的一个阈值,用于在不同的发送窗口下进行不同的算法选择
    当cwnd < ssthress时,TCP使用慢启动算法法 当cwnd > ssthress时,TCP使用拥塞避免算法
    当两者相同时两种算法都可以使用

拥塞避免算法

  1. 当进行拥塞避免时,cwnd每次收到ack后不在进行指数倍增加,具体增加的方法为 cwnd = cwnd + 1/cwnd,这样每过一个RTT,cwnd = cwnd + 1;因此拥塞避免阶段是线性上升的过程;

拥塞发生时:

分两种情况,RTO超时重传和快速重传.

RTO超时:

  1. ssthress将会被设置为当前窗口(拥塞窗口和通告窗口的最小值)的一半;
  2. cwnd重置为1;
  3. 进入新的慢启动过程;

由3个duplicate ack触发的快速重传:

  1. cwnd = cwnd/2;
  2. ssthresh = cwnd;
  3. 进入快速恢复算法;

快速恢复:

  1. cwnd = sshthresh + 3
  2. 重传重复的那几个ACK(即丢失的那几个数据包)
  3. 如果再收到重复的 ACK,那么 cwnd = cwnd +1
  4. 如果收到新数据的 ACK 后, cwnd = sshthresh。因为收到新数据的 ACK,表明恢复过程已经结束,可以再次进入了拥塞避免的算法了

拥塞状态机

机制

名词

  • 通告窗口
    技术解释:TCP流量控制的方法之一,在TCP两端在三次握手时就会声明自己接受窗口的大小来提供,窗口大小为字节数,每次发送ack确认数据包同时会传送当前的窗口大小,发送方发送的数据量不可以超过接收端窗口的大小,当窗口为0时,发送方将停止数据的发送
    flow control需要用到的指标.

SACK

使用SACK可以更快地确认丢包,而不必等3个相同序号的ack包才触发.那样会导致等太长时间才能够确认丢包(收到3个duplicate ack或者重传超时),使得网络利用率不足.

https://allen-kevin.github.io/2017/03/01/TCP%E9%87%8D%E7%82%B9%E7%B3%BB%E5%88%97%E4%B9%8Bsack%E4%BB%8B%E7%BB%8D/

重传定时器

https://allen-kevin.github.io/2018/01/02/TCP%E5%AE%9A%E6%97%B6%E5%99%A8%EF%BC%88%E4%BA%8C%EF%BC%89/

  • sysctl_tcp_retries1
  • sysctl_tcp_retries2
  • sysctl_tcp_syn_retries
  • sysctl_tcp_orphan_retries

零窗口探测定时器

nagle算法

TCP_CORK,把小包堆积起来发,200ms超时

延迟确认

TCP_NODELAY,回复ack时等有数据发送时一起发送,40ms

滑动窗口

发送端的滑动窗口:

  • 已发送且已收到ACK确认
  • 已发送但未收到ACK确认
  • 未发送但可以发送
  • 未发送也不可以发送

接收方的滑动窗口:

  • 已成功接收并确认
  • 未收到数据但可以接收
  • 未收到数据并不可以接收的数据