同樣的封包,截然不同的通道
到目前為止你學的一切,在空氣中仍然成立。封包依然是一張寫好位址的明信片;分層依然是層層相套的信封;訊框依然把位址放在最前面。當你的筆電透過 Wi-Fi、或你的手機透過基地台通訊時,裡頭那個 IP 封包,和一條導線會承載的完全相同。改變的只有堆疊的最底層——實體層與連結層,也就是真正把位元推過那道空隙的部分。所以整個這一階並不是一個新的網際網路;它是同一個網際網路,只是最後一跳變得艱難得多。
在導線上,通道幾乎無聊到剛剛好。一對銅線或一束光纖是私密、有屏蔽的隧道:你送出的訊號就是抵達的訊號,只是弱了一點,幾乎沒有別的東西混進來。良好有線連結的位元錯誤率小到不可思議——常常是十億或一兆位元裡還不到一個壞位元——以致上層大多可以假裝錯誤從不發生。一條無線連結把這份安逸丟掉了。空氣是與其他每一台無線電、每一台微波爐、每一面牆共用的,而訊號也不會沿著整齊的直線前進。這一階最重要的一句話是:無線並不是一條比較差的導線,它是一種根本不同的通道。
往上爬時把三個詞分清楚,就和你先前學過的一樣。頻寬是水管有多寬(每秒位元數),吞吐量是在扣掉損失與重試後你實際拿到的,而延遲是一個位元抵達要花多久。在無線上,吞吐量會隨著環境變化而逐秒劇烈擺盪——但這些都無法讓你贏過光速,所以更多頻寬仍然不會削減延遲。把這三者分開把握,能讓你對「更快的 Wi-Fi」或「5G」究竟承諾了什麼保持誠實。
訊號會衰減,而雜訊從不睡覺
從最溫和的問題開始:訊號單純會隨距離變弱。這就是衰減,而在無線電上它非常殘酷。功率不是隨距離線性下降,而是在開闊空間中大致與距離的平方成反比——距離加倍,訊號可能掉到四分之一,而牆壁、樓板、甚至你自己的身體還會偷走更多。這就是為什麼離路由器一個房間時你滿格,隔著兩道混凝土牆時卻龜速。導線也會衰減,但既可預測又緩慢;空氣的衰減則在有人關門、或有人走到你與存取點之間的那一刻就改變。
若空氣中只有它一個,微弱的訊號其實也還好。但事情並非如此。接收端還會聽見雜訊——它自己電子元件裡的熱噪聲——再加上同一批頻率上其他每一台裝置的干擾。真正決定一個位元能否存活的,不是訊號的原始強度,而是訊雜比(SNR):你的訊號相對於其他一切有多大聲。安靜房間裡一個清楚的聲音很容易聽見;同樣的聲音、同樣的音量,在吵鬧的酒吧裡就被淹沒了。基礎那一階講過的夏農老定理在這裡狠狠咬人:通道的容量隨 SNR 上升,所以當你的訊號衰減、雜訊卻不變時,誠實的最高資料速率就下降。這就是為什麼微弱的 Wi-Fi 連線不只是感覺慢——這條連結是真的協商出一個較低的速率,好讓位元仍然可讀。
多路徑:訊號不只抵達一次
現在來看所有無線問題中最奇怪的一個,一個在導線上完全沒有對應物的問題。無線電波會反射。離開你手機的訊號,到塔台並不是只走一條路——它走很多條。一份副本直直飛去;另一份從一棟建築反射;又一份從地板、天花板彈回。每一次反射走的距離都略有不同,所以這些副本在略有不同的時間抵達。這就是多路徑傳播:接收端聽見的不是一個訊號,而是同一個訊號一堆模糊的回音,在時間上被抹開了。
想像對著峽谷喊一個字:你聽見那個字,接著聽見它的回音,而若回音與你喊出的下一個字重疊,聽者聽見的就是一團糊。多路徑同時做了這兩件壞事。當同一個位元的兩份副本幾乎對齊抵達、相位卻略有偏差時,它們可能彼此抵消——形成一個死點,把手移個幾公分就能讓訊號恢復(這就是衰落)。而當一個位元的回音抹進下一個位元的抵達時,符號就糊在一起,這稱為符號間干擾。導線從不會有這個問題,因為隧道裡只有一條路。
WIRE: sender ----------------------- receiver
one path, one clean copy arrives
AIR: sender ===> direct path ==========> receiver
sender ===> bounce off wall =====> receiver (a bit later)
sender ===> bounce off floor ====> receiver (later still)
receiver hears: | | | . | | . . | same bits, smeared in time美妙的轉折在這裡:現代無線電把這個詛咒變成了一項功能。Wi-Fi 與 4G/5G 使用一種巧妙的方案(OFDM),把通道切成許多狹窄的子通道,每一個都慢到讓回音在下一個符號之前安定下來——於是抹開不再傷人。更棒的是,配上數根天線(MIMO),接收端能把不同的反射副本當成各自獨立的串流來聽並加總起來,甚至能一次送出好幾條獨立的串流。曾經摧毀訊號的回音,變成了額外的容量。這裡你不需要那些數學;只要記住一個觀念:多路徑是空氣這個媒介最具代表性的難題,而克服它,正是無線之所以變快的大部分原因。
你聽不見的那場碰撞
現在回想你在區域網路那一階遇到的共用纜線乙太網路。當許多機器共用一條纜線時,規則是 CSMA/CD:說話前先聽,若傳送途中偵測到碰撞就停下並退讓。關鍵字是「偵測」——在導線上,發送端能在傳送的同一瞬間聽著纜線,注意到兩個訊號撞在一起。在空氣中,這招辦不到。一台正在傳送自己訊號的無線電是用最大音量在喊;另一個發送端碰撞所產生的微弱遠方訊號弱了上百萬倍,完全被自己的發射機淹沒。無線發送端在傳送時,根本聽不見碰撞。
所以碰撞偵測出局了,無線必須改為設法在碰撞發生「之前」就避免它——一種叫碰撞避免的方案,下一篇會完整拆解。但避免本身有它自己深層的失靈,現在值得先看清它的樣貌。想像三個節點排成一列:左邊的筆電 A、中間的存取點、右邊的筆電 C。A 和 C 都在中間的訊號範圍內,但兩者距離太遠、彼此聽不見。A 聽了聽,沒聽到 C 的任何聲音(它聽不到——C 在範圍之外),於是開始傳送。C 也一樣。在中間的存取點那裡,兩者的訊號碰撞、雙雙報廢——然而 A 和 C 誰也沒聽見對方,因此都不知道自己本該等待。
那就是隱藏終端問題,它之所以有名,是因為它顯示出:當節點無法彼此都聽見時,「說話前先聽」並不夠。解法是去問接收端,而不是問通道:發送端悄悄請求傳送的許可,而能聽見每個人的存取點批准它、並要其餘的節點先按兵不動。那個請求傳送/允許傳送的交握,也就是 RTS/CTS 的做法,正是 Wi-Fi 繞過隱藏終端的方式,也是下一篇的核心。現在只要記住這條推理鏈:無線電聽不見自己的碰撞,所以偵測辦不到,所以無線必須避免碰撞,而連避免都很難,因為隱藏的發送端彼此感測不到。
為什麼這一切會把上層搞糊塗
退一步,把空氣這個媒介的四個硬道理收攏起來,因為後面每一篇都倚賴它們。訊號隨距離與障礙物衰減(attenuation),所以範圍既短又不穩。雜訊與干擾從不停歇,所以可用速率隨訊雜比起伏。回音層層堆疊(multipath),所以原始位元會糊掉,除非巧妙的編碼把它們救回。而損失既常見又成串地發生,而非偶一為之,這給了無線一個又高又變動的位元錯誤率。這些沒有一個是你設備的缺陷——它們是共用開放空氣的物理本質。
尾巴上的那根刺在這裡,也是現在值得連根拔起的一個真正的迷思。你在傳輸那一階遇到的經典 TCP,把封包遺失讀成壅塞的訊號——它的壅塞控制假設遺失一個封包代表某個路由器佇列滿溢,於是用力煞車、放慢下來,像一位謹慎的駕駛鬆開油門。在導線上,這個假設幾乎總是對的。在無線上它卻常常失準:一個封包遺失,不是因為網路壅塞,而是因為在一個衰減、吵雜、滿是回音的通道裡某個位元翻轉了。TCP 照樣煞車,扼住了一條其實還很寬鬆的連線。那個錯配——TCP 把無線遺失誤讀成壅塞——正是這一階最後一篇存在的理由,而現在你能清楚看見它為什麼會發生。