一、滑动窗口
rwnd:
接收端窗口,接收方在每次发送ACK确认报文时,会包含一个 rwnd (Receive Window Size) 字段,指明自己当前剩余的接收缓冲区大小(即可用窗口),这里是否是socket的接收缓冲区,如果未被即时会被覆盖,那么何来缓冲区大小剩余一说。还是说它是系统的缓冲区,还没提交给socket缓冲区的那个缓冲区。
?
cwnd:
发送方的拥塞控制窗口,它根据reno,cubic,bbr等算法来确认cwnd的窗口大小。
慢启动
拥塞避免
其中快重传:它是对超时重传的优化,等到超时已经很晚了。它是收到三次重复ACK,则启动RTO,即拥塞窗口减半。当发送端发送了5个tcp段时,1,2,3,4,5。接收端收到了1后,发送了对2的期望ACK-2,依次收到3 4 5后,分别依次发送ACK-2。这样就有了四个ACK-2,后面三个称为对第一个的重复ACK。
MTU(Maximum Transmission Unit):网络层传输的最大单元,通常以太网为1500字节。
MSS=MTU - IP头部(20字节) - TCP头部(20字节)。 //MSS 通常为 1460 字节
tcp段与序列号:tcp把要传输的数据当成字节流,从第一个字节开始,给一个一开始商量号的序号number,往后每个字节的序号都累加1。一个MSS为1460字节。那么一个tcp段序号范围可以为1~1460。
例如,发送端发送 5000 字节数据,MSS 为 1000 字节,数据可能被分割成 5 个 TCP 段:
段 1:序列号 1-1000(1000 字节)
段 2:序列号 1001-2000
段 3:序列号 2001-3000
段 4:序列号 3001-4000
段 5:序列号 4001-5000
超时重传:也称为RTO,超时重传说明网络已经很严重了,它是最后一到保险,因为快重传阶段,服务器返回的三次重复ACK也可能丢失。
1.发送端发送一个 TCP 段后,启动一个重传定时器。
2.如果在 RTO 时间内未收到该段的 ACK,发送端重传该段。
3.重传后,TCP 通常将拥塞窗口(cwnd)重置为最小值(例如,1 MSS),进入慢启动阶段。
SRTT = (1 - α) * SRTT + α * 样本 RTT //通常 α = 0.125(1/8)。
RTTVAR = (1 - β) * RTTVAR + β * |SRTT - 样本 RTT| //RTT 方差(RTTVAR)
RTO = SRTT + max(G, K * RTTVAR)
G:时钟粒度(通常为 100ms 或更小)。
K:常数,通常为 4。
tcp中,RTO 至少为 1 秒(RFC 6298 建议),某些实现可能设置最小值(如 200ms)。
如果超时重传失败,RTO 会翻倍(例如,1s → 2s → 4s),直到达到最大值(通常 60 秒)
QUIC(RFC 9002)建议 RTO 最小值 100ms。
kGranularity = 1ms(符合 RFC 9002)
二、吞吐量的计算
吞吐量又称单位时间内有效传输数据量,是被ACK确认已经到达对方的数据量。带宽是指实际的物理/硬件条件能提供的最高上限的吞吐量。因此吞吐量<=带宽。
吞吐量 ≤ MSS / RTT * C / sqrt(p)
其中:MSS:最大段大小(Maximum Segment Size)RTT:往返时延p:丢包率C:常数(通常接近 1)
在无丢包(p≈0)的情况下,简化为:
吞吐量 ≈ 窗口大小 / RTT
这里这个窗口就是min(rwnd, cwnd)。
比如现在rtt为20ms,吞吐量为20M;如果现在突然执行以下命令
tc qdisc add dev eth0 root netem delay 200ms limit 10000
由于窗口大小不变,必定导致吞吐量减少为2M。这就像船载人过河,如果河变宽2倍,那么运输效率就会减少为1/2。这个时后需要提升的是船每批运送的人的数量。
那么由于这个命令只是把时间增加了,并没有减少带宽,这个时候由于tcp的拥塞避免,会缓慢增加窗口大小,直到丢包或超时。恢复到之前的吞吐量大小。
附录:
picoquic的picoquic_internal.h中,有如下定义:
PICOQUIC_INITIAL_RTT: 初始 RTT 设置为 250ms(250000 微秒)。
PICOQUIC_INITIAL_RETRANSMIT_TIMER: 初始 RTO 设置为 250ms(250000 微秒)。
PICOQUIC_INITIAL_MAX_RETRANSMIT_TIMER: 最大初始 RTO 为 1 秒(1000000 微秒)。
PICOQUIC_MIN_RETRANSMIT_TIMER: 最小 RTO 为 50ms(50000 微秒)。
PICOQUIC_LARGE_RETRANSMIT_TIMER: 大型重传定时器为 2 秒(2000000 微秒)。
PICOQUIC_ACK_DELAY_MAX_DEFAULT: 默认最大 ACK 延迟为 25ms(25000 微秒,符合 RFC 9002)。
PICOQUIC_ACK_DELAY_MIN: 最小 ACK 延迟为 1ms(1000 微秒)。
PICOQUIC_ACK_DELAY_MAX: 最大 ACK 延迟为 10ms(10000 微秒,具体值可由对端协商)。
如果rtt为20ms,且有以下条件:
RTTVAR ≈ 0ms(网络稳定,抖动极小,假设初始 RTTVAR 为 1ms)。
max_ack_delay = 25ms(使用 PICOQUIC_ACK_DELAY_MAX_DEFAULT)。
kGranularity = 1ms(符合 RFC 9002)。
计算quic的RTO为49ms。
RTO = SRTT + max(4 * RTTVAR, kGranularity) + max_ack_delay= 20ms + max(4 * 1ms, 1ms) + 25ms= 20ms + 4ms + 25ms= 49ms