第三章 數據鏈路層-Data Link Layer
3.1數據鏈路層概述
數據鏈路層是我們接觸到的第一個網絡層次,同時也廣泛的存在於我們的生活中。由於一些同學會在學習過程中把不同網絡層次的內容搞混,所以我覺得有必要先對數據鏈路層做一個整體的描述:數據鏈路層所考慮的內容只與本地節點之間的數據交付(local delivery of frames)有關。換句話說,單個數據幀不會超出局域網的范疇(數據幀是鏈路層的一個傳輸單元),而所謂“節點”,可能只是一台本地機器,也可能是一個連接到了網絡層的設備,或者是一個集線器,把數據連向另外一個本地網絡。
數據鏈路層使用物理層提供的服務,在通信信道上發送和接收比特。它的主要任務是將一個傳輸設施轉變成一條沒有漏檢傳輸錯誤的線路。發送方需要將網絡層的數據拆分成數據幀,然后按照順序發送他們。一個數據幀可能會有幾百到幾千個字節長度。在實現自己目標的過程中,可能會遇到各種各樣的問題(比如信道占用、數據傳輸出錯、接收方數據處理能力太低...等等)。為了保證這些比特流成功的發送到鏈路的接收方,鏈路層需要考慮設計一種合適的幀結構以拆分數據,一個合適的流量控制系統防止發送端的數據淹沒接收方,一個糾錯或者驗錯系統發現並解決傳輸中的錯誤,以及一種決定誰來發送數據的協議(這一部分會在第四章中展開)。
下面對數據鏈路層做一個簡單的刻畫,讀者可以通過鏈路層的功能和提供給上層的服務來認識這一層。
3.1.1主要功能:
- 為網絡層提供接口
- 通過單個鏈路傳輸數據幀(frame),其中包括以下兩個功能:
- 處理錯誤handle errors
- 調節數據流 Regulate flow data
3.1.2 提供給網絡層的服務
- 無確認無連接的網絡(802.3如以太網)
- 有確認無連接的網絡(如802.11無線局域網)
- 有確認有鏈接的網絡(如衛星信道、無線電話)
3.2 成幀方法
前面已經說到,數據鏈路層通過發送數據幀進行交互。下面具體講解一些數據鏈路層中幀的結構,以及通過這些特殊設計的結構,數據鏈路層可以提供的服務(尤其指糾錯與驗錯)。
3.2.1數據鏈路層幀的結構
數據鏈路層將網絡層的數據包(packet)封裝進一個幀(frame)里。這個過程通過給包添加幀頭和幀尾來實現,如下圖。
3.2.2成幀
當數據在電線中進行傳輸時,必須被分成可辨識的數據塊。因此,需要接收器和發送器達成一種共識,明確發送的一連串二進制數據中,有哪些屬於同一個幀。這部分的內容即是針對這個問題展開的。這些方法總稱為拆分比特流的成幀方法:
1-字節計數法(Byte Count)
可見,在每個frame前面,都會添加一個字節的數據來存儲本幀大小。接受方接收到第一個字節,便可以得知這一幀的范圍。這么做的問題在於,一旦關鍵字節傳輸錯誤(這種情況在不穩定的連接中有可能發生),后面的數據都存在識別錯誤的風險。
2-字節填充法(Byte Stuffing)
基於此,人們進行了一些改進。現在不再通過幀頭計數的方法區分不同的幀,而是使用一個特定無實際含義的標志來作為幀和幀的邊界(在這種方法中,同樣是一字節大小)。但是這么一來,由於原始數據中很可能出現同標志FLAG一樣的字節,很有可能產生歧義,因此需要很復雜的轉義操作。(想想c語言中的轉義符號)
上圖中,轉義字節是ESC,標志字節是FLAG。如果原數據中就有FLAG,那么需要在FLAG前加上ESC;而如果原數據本來包含ESC FLAG,就需要在這兩個字節前面都加上ESC...這個問題可以一直遞歸下去。(狗頭
3-位填充(Bit Stuffing)
位填充的思路和之前的字節填充類似,但是這次增加的不再是比特位,而是以6個連續的1作為標志;至於之前的轉義問題,則使用了另一種巧妙的方法解決:
在發送時,機器每遇到5個連續的1,就會在后面添加一個0。相對應的,接受時,每遇到5個1就會去掉后面的一個0。這樣一來,6個連續的1可以很好的標記出幀的邊界。
4- 三種方式的優缺點如下:
字節計數 | 在每一個幀前面設置一個計數器,記錄該幀里面一共有多少字節 | 當然這種方式並不可靠,其問題在於:計數值可能因為一個傳輸錯誤而弄混 |
字節填充 | 用特殊的標志字符(字節)來界定幀,如,這個字符可以是01111110這個字節(同時,為了防止與原始數據中的內容沖突,可能需要對原數據進行轉義。轉義時,在原數據對應字節前加上一個ESC) | 使用轉義符的方法的確解決了原數據種含有沖突內容的情況,但是因為ESC同樣也是一個字節,在原數據中出現時也有可能出現混淆的情況,比較麻煩。 |
位填充(主流!) | 幀標志由6個連續的1組成;在傳輸是,每有5個連續的1,就在后面添加一個0;在接受的時候,每有5個連續的1,就把后面的0刪除 | 保證了透明傳輸:數據中的任意組合不引起幀邊界判斷失誤 |
3.2.3 差錯控制&流量控制
這個子標題中,我們先對差錯控制與流量控制建立起一個基礎的概念,之后再詳細展開。
差錯控制的目的在於確保傳遞的可靠性。然而實際情況總是很復雜的,需要一個方法應對數據幀丟失、錯誤、冗余等等問題。數據鏈路層引入了計時器和序號來解決這個問題;而流量控制,顧名思義,就是對傳送中的數據的流量進行控制,通過特定的協議選擇一個合適的收發速率,以使接收方有足夠的緩存空間來接受每個幀。流量控制的方法大體分為兩種,一種是基於反饋的流量控制,另一種是基於速率的流量控制。前者要求接收方發送消息,來確認接收方的狀態(如發送是否過快,等等);后者通過協議內置的機制直接限制發送方的發送速率。本章將學習基於反饋的流控方案。
3.3 檢錯與糾錯
下面講一下數據鏈路層怎么發現錯誤。在物理層的傳輸過程中,總有可能出現傳輸錯誤或丟失的情況。鏈路層有兩種錯誤的應對策略。兩種方式都在原幀中插入冗余信息,其中一種使用糾錯碼,使得接收方可以推斷出原先的內容;后一種使用驗錯碼,使得接收方可以知道傳輸出錯,從而提醒發送方重新發送。
- 總體上,都使用了增加冗余信息的方法
- 糾錯碼:海明碼,二進制卷積碼,里德所羅門碼,低密度奇偶校驗碼
- 驗錯碼:奇偶,校驗和,循環冗余校驗(CRC)
3.4 數據鏈路層經典協議
在這個子標題中,我們繼續談論一些好玩的東西。
3.4.1 三種經典協議(單工)
下面從簡單情況下開始,討論幾種經典的傳輸協議。以下的幾種協議討論的全部是單工式的,所謂單工,指的是數據只能在通信信道上單項傳輸。同理,還有雙工和半雙工兩種模式,指的分別是:數據在某一信道上可以同時沿兩個方向發送和是指數據可以沿兩個方向傳送,但同一時刻一個信道只允許單方向傳送
一個烏托邦式的單工協議
之所以稱為烏托邦式,就是因為這個協議討論的情況十分理想,來看看它的成立條件:
- 不考慮數據傳輸出錯(通信不會丟失或者損壞幀)
- 數據只能單向傳播(單工!)
- 可用的緩存無限大,不考慮數據處理時間
在這種情況下,發送端只需要直接發送數據即可,不需要考慮多余的因素。盡管以上三個條件不太可能出現在現實應用中,但烏托邦式協議的貢獻在於提供了一種協議的基礎,我們可以在此基礎上一步一步的做一些改進。
無錯信道上的單工停-等式協議
這一回我們將考慮數據傳輸的問題。假如發送方的發送速度高於接受方的速度,接收方將很快被數據淹沒。所以在這個協議中,最明顯的區別是加入了停-等的概念(stop and wait)。即:發送方每發送一幀,都會停下來等待接收方的確認。收到確認后才會繼續發送新的信息。
有錯信道上的單工停-等協議
既然發送的幀有可能會出錯或者丟失,那么就需要一種機制可以有效地對傳送失敗的內容進行重傳。
一方面,為了防止傳輸數據丟失而接收方還在等待的情況發生,我們引入了計數器來解決這一問題。
另一方面,我們引入自動重復請求(Automatic Repeat reQuest),使得發送方在發送下一個數據前,必須等待一個肯定的確認。
3.4.2滑動窗口協議(Sliding Window Protocol)
在以下的部分中,我們將去掉原先單工信道的預設。這一部分中,一條鏈路可以傳輸兩個方向的數據。
在這種情況下,我們可以通過捎帶確認的方法優化我們的協議。
- 稍待確認:接收方暫時延緩確認,取而代之的,讓確認消息搭載在下一個出境的數據幀上的技術。
所有的滑動窗口本質是,在任何時刻,發送方總是維持着一組序號,分別對應於允許它發送的幀。這些幀落在發送窗口內。類似的,接收方也維持着一個類似的接收窗口對應着一組允許它接受的幀。
下面這張圖片可以幫助各位看官加深理解。
1位滑動窗口協議
一位滑動窗口協議是滑動窗口協議中最基礎的一個協議。在這個情況下,接收方和發送方的窗口大小均為1。
下圖描述了一個典型的一位滑動窗口協議。協議可能出現的問題在於,當A和B同時發起通信,每一幀都會被多次重復發送,嚴重浪費了帶寬。
回退N協議(Go Back 'N')
在這個協議中我們將考慮一些更加復雜的情況。這里,幀在鏈路上的傳輸時間也會被納入考慮范圍。既然每一個幀都會花費相當多時間在鏈路上傳輸,那么接收方應當更加合理的利用這段時間,達到更高的傳輸效率。一種解決技術被稱為管道化。
管道化:保持多個幀同時在傳送的技術。
那么接收方和發送方應當使用什么樣的技術以保證一個最大化的數據傳輸速度呢?回退N協議解決的正是這個問題,見下圖:
圖:數據丟失后丟掉后續所有幀
可見,在GBN協議中,接收窗口大小是1,當出現了傳輸錯誤或者丟包的情況后,接收方便會簡單的丟棄所有后續到達的幀,並向發送方發送一個NAK否定確認。發送方會重新發送出錯的幀及其后所有的幀。
讀者請注意,GBN協議是基於滑動窗口的,但它不再屬於停-等式協議。GBN協議有着不錯的傳輸效率,但是假如網絡狀況很差,GBN將會導致大量的數據重新發送,其效率可能反而不如停-等式。而之所以會出現這樣的情況,就是因為數據幀在鏈路中傳播的延遲問題。
選擇重傳協議(Selective Repeat )
在選擇重傳協議中,接收窗口大於1。但區別於GBN中直接丟棄所有幀,在SR中接收方只丟棄掉壞的幀,仍會接受之后好的幀。見下圖:
至此,數據鏈路層的主要協議已經描述完畢,請讀者移步下一章: 第四章 介質訪問控制子層