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


引言

 

  對於程序猿來講,似乎越接近底層,就越顯得高大上。這也算是程序猿們的共同認知吧,雖然不是所有人。今天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只想說,你懂的。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM