TCP/IP中最高大上的鏈路層簡介

lvxfcjf發表於2021-09-09

引言

  對於程式猿來講,似乎越接近底層,就越顯得高大上。這也算是程式猿們的共同認知吧,雖然不是所有人。今天LZ就和各位一起探討一下TCP/IP中最高大上的一層,也就是最底層的鏈路層。

  這一層LZ瞭解的還不夠深刻,但是LZ還沒有做硬體的打算,因此LZ覺得只要能夠大致明白其原理即可,有的時候太執著了並不是好事,別忘了執著的同義詞中有一個叫鑽牛角尖。

 

鏈路層是什麼

 

  這個問題其實很好回答,在上一章LZ就提到過,直觀的說,鏈路層就是我們平時接觸的網路卡和網路卡的驅動程式(當然,也可以指其它的網路介面和驅動,比如3G網路卡和驅動)。

  接下來回答另外一個問題,鏈路層是做什麼的?

  這個我們可以類比一下,既然鏈路層可以看作是網路卡和網路卡驅動程式的總稱,那麼網路卡和網路卡驅動程式是做什麼的,鏈路層就是做什麼的。這樣我們就比較好理解了,要搞清楚鏈路層是做什麼的,只需要搞清楚網路卡以及網路卡驅動程式是做什麼的即可。

  網路卡,很顯然,它是資料傳輸過程中,一個主機(也就是我們所謂的PC機)資料的入口與出口,就像是一個城市的火車站一樣,你來北京需要經過火車站,離開北京也需要經過火車站(從天上飛過來飛過去的土豪不算)。

  這個入口和出口可不是隨便讓你製造的,你必須按照一定的協議去製作(比如乙太網協議)。大家會發現,我們的網路卡插口都是一樣的(網線的插頭也都是一樣一樣的),這可不是巧合。網路卡網線這都是有形的網路卡介面,同樣的,對於無線網來講,儘管它沒有讓我們看得見摸得著的介面,但道理是一樣的,它在製作的時候也要遵循一定的協議(比如wifi)。

  網路卡驅動程式就比較好理解了,網路卡按照一定的規則傳輸資料(比如頻率多大?一次傳多少?等等),相應的,這些規則也需要一個軟體來封裝和解析,這些工作正是網路卡驅動程式完成的。這有點類似於計算機硬體和作業系統的關係,如果沒有作業系統,你要那一堆破銅爛鐵它能給你幹活嗎?比如你現在想計算1+1=2,你能直接拍CPU一巴掌,它就給你幹了嗎?肯定是需要你透過作業系統,把兩個1先存到CPU的儲存器當中(比如暫存器),然後呼叫CPU當中的運算器,才能最終把結果計算出來。

  網路卡也是一樣的,如果沒有網路卡驅動程式去控制它,你拍它一巴掌它是不會給你傳資料的,需要驅動程式把你要傳的資料封裝一下,然後交給網路卡,網路卡一看,我靠,這要傳的地址不就是隔壁家的鳳姐嗎,於是網路卡才開著電纜把你的求愛信件送給鳳姐。

  一般在驅動程式交給網路卡的資料中,都帶有源實體地址(也就是傳送者的網路卡實體地址,這玩意有時候會有用,但一般沒啥用),目的實體地址(告訴網路卡把資料送給誰)以及協議型別(用於對方接收到資料後用同樣的協議解析),比如0f:00:11:0d:01:12這種形式的東西,是不是感覺很熟悉呢?它就是網路卡的實體地址格式,是48位的二進位制數字(也就是6個位元組,中間用冒號分割),用ifconfig或者ipconfig命令就能看到你的網路卡實體地址。

  

TCP/IP與OSI

  

  記得上一篇博文中,還有猿友留言,說LZ把物理層給丟下了。看來有不少猿友,還是停留在OSI的七層模型中。OSI和TCP/IP究竟是什麼關係,接下來就由LZ來為大家簡單解釋一二。

  OSI共有七層,分別是物理層,資料鏈路層,網路層,傳輸層,會話層,表示層和應用層。而在第一章當中,LZ介紹過TCP/IP協議族共有四層,分別是鏈路層,網路層,傳輸層和應用層。

  簡而言之,它們最大的區別是,OSI只是參考模型,而TCP/IP是目前實際使用的一個協議族,它已經被大部分作業系統所實現。它們的對應關係如下。

  可以看到,TCP/IP協議族簡化了OSI模型,其實這種現象在實際的開發過程中也很常見,LZ舉個簡單的例子大家就清楚了。

  相信web專案的開發大部分猿友都不陌生,一般情況下,我們們的分層是Action,Service,Dao這種三層方式,但是在實際開發中,往往不一定按照這個分層去開發。比如有些比較小的專案,會刪除Service這一層,由Action直接引用Dao。

  這其實就和OSI與TCP/IP的關係一樣,參考模型始終是參考用的,實際當中不一定就得按照這個去實現。

  

鏈路層存在的意義

 

  人生在世,要活的有意義才算沒白活一場。小的時候,LZ活著的意義是希望有一臺小霸王遊戲機,後來LZ活著的意義是希望有一臺可以玩傳奇的PC機,再後來LZ活著的意義是希望有一個37度的女娃娃。

  咳咳...跑題了。言歸正傳,TCP/IP中的每一層都應該有它存在的意義。說到這,不禁會讓人產生一個疑問,就是鏈路層存在的意義是什麼?

  很簡單,LZ還是用一個例子來說明。Java中有Jdbc,是一個標準的Java資料庫操作API。LZ想請問各位猿友,這套API的意義是什麼?

  它的意義就在於,讓資料庫差異導致的一些細節變化對開發人員透明。透明這個詞實在是太貼切了,透明的意義就在於“你不知道也不需要知道”。套用這句話,就是Jdbc讓開發人員不知道也不需要知道資料庫當中的一些操作細節,只需要按照API的操作說明去呼叫就可以了。這樣帶來的好處就是,降低了開發人員的學習成本,也增加了程式的擴充套件性和健壯性。因為你不再需要分別去了解mysql的資料庫連線細節,或者oracle的資料庫連線細節,你只需要知道DriverManager.getConnection()可以給你一個資料庫連線就行了。

  我們再回到剛才的話題,鏈路層存在的意義與Jdbc特別相似,它讓物理傳輸的細節對上層是透明的。套用剛才那句話,也就是說,上層(比如網路層,傳輸層等等)不知道也不需要知道資料在物理上是如何傳輸的。比如資料究竟是用雙絞線傳輸的還是用同軸電纜,到底是有線的網路介面還是無線的網路介面傳輸,這些細節統統不需要鏈路層的上層去操心。

  這樣做的好處就在於,鏈路層給上層提供了一層封裝,就像Jdbc給開發人員提供的一層封裝一樣。只要是基於Jdbc開發的程式,資料庫廠商只要都提供Jdbc的實現,開發人員就可以輕易的把資料庫切換。同樣的,只要是基於鏈路層的協議,網路層包括更高層也可以輕易的切換鏈路層實現。比如一會使用有線,一會使用無線,這對於處於網路層的IP實現,或者是傳輸層的TCP實現來講,是不需要有任何變化的。當然了,對於處於應用層的Http實現更不需要有任何變化,這就像你開發的web程式,難道把有線網變成無線網就需要改程式碼嗎,當然是不需要的!

  所以,現在很清楚了,鏈路層存在的意義,用簡單的一句話概括,就是它讓上層可以不需要考慮資料物理傳輸的細節,更加專注於自己該做的事。這種思想多麼像MVC分層設計的初衷,MVC的初衷不就是為了讓每一層可以專注於做自己的事嗎,比如控制層就只專注於業務邏輯,檢視層就只專注於介面展示,模型層就只專注於應用程式與資料庫的互動。

  

文章花絮

 

  很多時候,我們總是糾結著自己的糾結,但在現實當中,往往很多事情是沒有標準答案的。以前,學習數學的LZ習慣性的認為,任何事不是對就是錯,沒有模稜兩可的區域。

  在社會中磨礪的時間久了,就會意識到,很多時候,沒有對錯,只有結果。從這個角度來看,只要你朝著好的結果去努力,那麼你就是對的,哪怕在某種意義上你是錯的。因為只要結果是好的,你最終會被認為是對的。

  成功者不要在意過程,失敗者不要在意結果。LZ只想說,你懂的。

  

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3486/viewspace-2808362/,如需轉載,請註明出處,否則將追究法律責任。

相關文章