1. 程式人生 > >資料鏈路層的成幀方法

資料鏈路層的成幀方法

       之前說過,資料鏈路層一個很重要的功能就是成幀和拆幀,因為幀是資料鏈路層的一個單元,資料鏈路層是對於幀進行處理的。那麼這裡就具體講一講資料鏈路層是怎麼成幀的。

       首先我們應該想想成幀所涉及的問題。第一就是網路層的資料包交給鏈路層之後,按照怎樣的格式封裝成幀?第二就是,用什麼來區分幀頭和幀尾?也就是什麼時候幀開始,什麼時候結束的問題。以及,怎麼看傳送的幀是對的?能不能看出來幀的某個位元錯了?這些都是成幀機制應該考慮的,所以幀的格式設計成如下這樣:


        能看出來,幀的組成主要是標誌和欄位兩個部分,標誌主要是標識了幀的開始和結束,欄位部分主要有地址欄位,控制欄位,正文欄位和校驗欄位四個部分。地址欄位表明了幀的去向和來源,這是硬體的網絡卡地址,控制欄位就是各種協議,正文欄位是真正的資訊,校驗欄位是用來檢驗幀是不是有錯誤,通常有CRC校驗等等。這樣來看,上面的幾個問題就都解決了。標誌是成幀的一個重要標誌,鏈路層讀到標誌,就知道幀開始了,這也就界定了一個幀的範圍。對於正文欄位,鏈路層讀不懂,他也不會在意正文欄位是什麼,他眼中的正文也就是一串0101而已。

資料鏈路層成幀的方法主要有三個:字元計數法,字元填充的首尾界定法和位元填充的首尾界定法。

1.字元計數法 用一個幀的第一位元組來說明幀的總長度(總長度包含這個幀頭)


        看這張圖,白色為幀頭,指明瞭長度,比如第一幀長度為5,後面就跟了4個位元組,第二幀的長度為5,後面也跟了4位元組,之後是兩個8位元組長度的,所以各自跟了7位元組的正文部分。但是很顯然,如果頭這一個位元組出了問題,影響的就不僅僅是這一幀了,其他的都會出問題。比如:


        第二個幀頭出了問題,那麼就會出現大問題:後面的全部幀都會出錯,連鎖反應。所以這種方法不太常用。

        2.字元填充的首尾界定法

        在幀的頭之前和尾之後加一個特殊的字元,只要讀到這個字元幀就開始了,再次讀到就認為這個幀結束了,如下圖所示:


        這種方法能夠避免上面字元計數法的頭出錯問題,但是他也有問題:如果正文裡面出現了flag特殊字元怎麼辦?解決辦法是在正文裡面flag字元前面加上轉義字元esc,這樣讀到flag之前如果沒有轉義字元esc,那麼認為幀結束,如果有esc那麼認為他就是普通的資料就行。問題又來了,那麼正文裡面如果有esc字元呢?那麼就在esc前面再加一個esc就行了,這兩個的處理是一樣的。如下圖:


      3.位元填充的字元界定法

       這種方法和第二種比較類似,區別是他把flag具體化了,為6個1。這樣當正文讀取的時候一旦出現了5個連續的1,那麼在後面填充一個0,避免出現6個1造成幀提前結束。如下圖所示:


       收端接收到之後,每讀到5個連續的1之後,就把後面的0去掉一個,這樣就得到了原文的資料了。

       上面三種方法就是最常見的鏈路層成幀的方法。