802.11a/g wifi 路由器上標稱的是 54Mbps,除個8,至少也有 6MB/s 啊。為什么實際速度只有 2M 多呢?網上的解釋大多語焉不詳,我只好班門弄斧了,歡迎指正。
Wifi 通信在一個給定的載波頻段(頻道)上進行,就像大家在大廳里說話一樣,每個人說話都會干擾到其他人。
為什么不多搞一些頻道呢?一方面,可以不申請許可就使用的 ISM 頻段在適合無線通信的 2.4GHz 區域是很有限的;另一方面,為了保證通信速度,頻道不能太窄。在 802.11a/g(wifi 協議)中,頻道寬度是 22MHz,共劃分出 14 個頻道(其中有些頻道在有些國家不屬于 ISM 頻段)。每個頻道對周圍的頻道也有干擾(見下圖),這就是無線路由器有十幾個頻道,但只有相隔較遠的 1、6、11 頻道才能同時使用的原因。

聰明的讀者一定想到了,既然大家互相都能聽到,那么聽到旁邊沒有其他人在說話的時候再發言唄。這就是載波監聽(CSMA,Carrier Sense Multiple Access)技術。但問題不是這么簡單。
第一個問題是,如下圖所示,1、2、3 排成一條線,1要給2說話,此時3正在給2說話,但1不知道這個事實,2同時聽到1和3的話,就全亂了。在現實世界中,我們也許遇到過這樣的尷尬。

第二個問題是,人的耳朵和嘴巴是“全雙工”的,也就是能夠同時收發;但無線通信目前還沒有實現全雙工,也就是只能在收發之間切換,在說話的時候就聽不到周圍的聲音。因此,在發送過程中實時監聽載波,是不現實的。
為了避免沖突,802.11 引入了 Request to Send (RTS) 和 Clear to Send (CTS)。在下圖中,節點1要給2發送一幀,首先發送 RTS 幀。1周圍的節點聽到 RTS 后,就會沉默下來。目標節點2收到 RTS 后,會回復 CTS 幀,讓2周圍的節點閉嘴。1收到 CTS 后,就可以開始發送數據了。為了保證數據能被準確收到,2還要回復一個 ACK 表示確認。

無線天線發送和接收模式的切換需要時間,協議需要保證回復幀開始發送時天線已經從發送狀態切換到接收狀態,因此又增加了一些幀間隔。

其中,SIFS (Short Interframe Space) 是 RTS 和 CTS 的間隔,也是 CTS 和數據幀的間隔,也是數據幀和 ACK 的間隔。為了保證不發生沖突,從 ACK 結束后到下一幀開始傳輸之前,要有更長的 DIFS (Distributed Interframe Space)。在 802.11a OFDM PHY(正交頻分復用的物理層)中,這些間隔是:
- SIFS = 16 µs
- Slot time = 9 µs
- DIFS = 2 x Slot time + SIFS = 34 µs
802.11a 的最長幀長是 1536 字節,就是 12288 bit,加上6個表示糾錯編碼結束的額外 bit,共 12294 bit。根據下表,在 54Mbps 傳輸速度下,需要用 57 個符號。TCP ACK 有 76 個字節,加上6個額外 bit 共需要 614 bit,根據下表需要用 3 個符號。802.11 ACK 只需要1個符號。

在發送真正的數據之前,還要發送 Preamble。Preamble 是用于訓練接收方的,讓接收方知道什么樣的信號對應什么樣的數據,該用哪個天線接收等。這些 Preamble 需要 20 µs 才能傳輸完成。承載數據的每個符號需要 4 µs 時間傳輸。


TCP 的傳輸過程是,首先發送 TCP data,再回復 TCP ACK。傳輸 TCP data 和 TCP ACK 的過程,分別需要經過 DIFS、802.11 Data、SIFS、802.11 ACK。下表(摘自[1])計算出了一個 TCP packet 傳輸需要的時間。
| TCP data | TCP ACK | |
| DIFS | 34 µs | 34 µs |
| 802.11 Data |
20 µs + 57 * 4 µs/symbol = 20 µs + 228 µs = 248 µs |
20 µs + 3 * 4 µs/symbol = 20 + 12 µs = 32 µs |
| SIFS | 16 µs | 16 µs |
| 802.11 ACK |
20 µs + 1 * 4 µs/symbol = 20 µs + 4 µs = 24 µs |
= 24 µs |
| Frame exchange total | 322 µs | 106 µs |
| Transaction Total | 428 µs |
因此,每秒鐘能進行 1000000/428 = 2336 次 TCP packet 傳輸。1536 字節去掉 20 字節的 IP header 和 40 字節的 TCP header,就是 1476 字節的 TCP payload。這意味著數據傳輸速率可達 3.45 MB/s(1000進制)或 3.29 MB/s(1024進制)。考慮到 TCP 的滑動窗口協議允許在收到 TCP ACK 之前發送新的 packet,實際傳輸速度可能更快。
上述速率是理想情況下的理論速率。在真實的網絡環境中,
- 無線網絡幀長一般設置為 1500 字節而不是 1536 字節;
- TCP 發送方和接收方要競爭使用信道,會增加額外的控制開銷;
- 如果多個設備接入同一個接入點(AP),就要競爭使用信道,不僅要讓出一部分信道給其他人,還要增加控制信令的額外開銷;
- 無線網絡傳輸沒有有線那么穩定,信道的干擾和信源的移動都可能導致傳輸錯誤,需要重傳;
- TCP 本身還有擁塞控制機制,不可能一直以理論最高速率發送。
這些因素綜合起來,實測的數據傳輸速率只有 2.3 MB/s(1024進制)左右。從 3.29M 到 2.3M 還是有挺大差距的,上面哪個因素比較重要,或者還有什么我沒考慮到的因素,我還想不明白。歡迎各位朋友一起討論。