一、滑動窗口
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