1. 程式人生 > >網際網路協議入門

網際網路協議入門

作者:[DeppWang](https://depp.wang) 網際網路上的資料能從一臺裝置傳送到另一臺裝置,整個過程由[網際網路協議](https://zh.wikipedia.org/wiki/TCP/IP協議族)( Internet Protocol Suite)實現的。 對於網際網路協議,一直一知半解。知道會分為幾層,但為什麼分層,分層有什麼好處,都不甚理解。通過[阮一峰](www.ruanyifeng.com)的這兩篇文章,大概有了一個初步認識,下面是我對網際網路協議的理解。 - [網際網路協議入門(一)_阮一峰_](http://www.ruanyifeng.com/blog/2012/05/internet_protocol_suite_part_i.html) - [網際網路協議入門(二)_阮一峰_](http://www.ruanyifeng.com/blog/2012/06/internet_protocol_suite_part_ii.html) ## 一、五層模型 我也認為將網際網路協議分為五層,可以更好的去理解它,從上往下分別是:應用層、傳輸層、網路層、(資料)鏈路層(連結層)和物理層(實體層)。如果死記硬背,往往過幾天就忘了,所以需要了解其原理,當我們理解了全文,讓我們去說文章的名字,那還不是輕而易舉嗎! ![圖片來自阮一峰部落格](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214828685-911694039.png) 大多數文章或書籍都是從上往下來講解網際網路協議,但是個人感覺總是沒有深入其理,阮一峰**自下而上**的講解每一層的功能,讓人記憶深刻。我也依葫蘆畫瓢,先自下而上分析一下每一層的功能,再結合 [Wireshark](https://www.wireshark.org/) 抓包工具,來稍稍看看網際網路協議的真面目。 ### 1.1 層與協議 為什麼叫某某層?為什麼要分層?層是什麼? 我覺得層這個叫法很形象,一層一層,好像平行,各自獨立。維基百科的解釋是:「**整個通訊網路的任務,可以劃分成不同的功能區塊,即所謂的層級([layer](https://zh.wikipedia.org/w/index.php?title=Layer&action=edit&redlink=1))**」,我們可以理解為,每一層是實現了一個功能,有不同的分工。就跟寫程式碼一樣,如果把所有功能放一起,改一行程式碼就可能影響全部,所以根據不同功能拆成不同的方法。我覺得叫什麼不重要,可以叫應用塊、應用組,等等。**主要知道,每一層是為了完成一個功能就行。** 我們知道,每一層都有自己對應的協議(Protocol),比如,網路層有 IP 協議。那何為協議?跟這個層又有什麼關聯?維基百科上有這麼一句話:「網路層功能由 IP 協議規定和實現,故又稱 IP 層」。我們可以看出,每一層的功能其實是協議來規定和實現的。所以,協議可以理解為,**有大家都遵守的規則(規定),並負責去實現這個規則。** ## 二、物理層(Physcial Layer) 我們電腦現在不用插網線就能上網(連 WIFI),但是路由器插網線了,在家裡,路由器一般又需要通過一根網線連線入戶光纖盒(又稱為光貓),光纖盒又需要通過一根光纖連線到其他裝置。電腦連線 WiFi,電腦的資料傳送到路由器,是通過無線電波。所以傳輸資料需要物理載體,類似網線、光纖、無線電波。**我們將傳輸資料的物理載體稱為物理層(Physcial Layer)**。為什麼我們訪問美國的網站就慢一些,因為美國網站的伺服器在美國,資料通過海底光纜傳輸,耗時會久一些。這也是為什麼很多公司要在不同城市部署伺服器的原因之一吧。 資料在物理載體中傳輸,傳輸的是什麼呢?**是 0 和 1 組成的電訊號**,為什麼是 0 和 1 組成的電訊號呢?這個吧,姑且通過類比的方式來解釋,因為計算機只能識別 0 1 二進位制,所以要傳輸 0 和 1 組成的電訊號吧。 ## 三、鏈路層(Link Layer) 物理層只是一個傳輸載體,沒有「自主意識」, 我們需要藉助物理層上的[鏈路層](https://zh.wikipedia.org/wiki/資料鏈路層)(Link Layer),**鏈路層的功能:將資料從一處傳送到另一處**,鏈路層在傳送方和接收方都有,在傳送方:鏈路層將資料轉換為電訊號,並將其傳送出去;在接收方:鏈路層收到電訊號,並將電訊號轉換為資料。鏈路層和物理層之間的關係可以這樣表示: ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214829090-1430205152.jpg) 在[區域網](https://zh.wikipedia.org/wiki/區域網)內,將資料從一處傳送到另一處需要使用[乙太網](https://zh.wikipedia.org/wiki/乙太網)(Ethernet)。**區域網的通俗理解,連線同一個 [WiFi](https://zh.wikipedia.org/wiki/Wi-Fi) (路由器 Router)的裝置在同一個區域網內。** ### 3.1 乙太網 乙太網是一種區域網技術,它可以實現區域網內的裝置通訊,我們現在電腦一般連 WiFi,WiFi 可以認為是「無線乙太網」。 我們可以理解為,**在區域網內,鏈路層的功能其實是由乙太網實現的**(區域網外的鏈路層比較複雜,本文不討論)。 區域網內的鏈路層和乙太網的關係可以這樣表示(物理層作為乙太網的傳輸載體): ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214829375-1480032275.jpg) **乙太網需要規定電訊號的格式,以便雙方解讀**。乙太網規定一組電訊號為一個數據包,叫幀(Frame),幀包含兩部分,標頭(Head)和資料(Data),標頭包含傳送方地址、接收方地址等資訊,資料則是資料包的具體內容。我們一般將幀稱為乙太網資料包,或者[以太幀](https://zh.wikipedia.org/wiki/乙太網幀格式),以太幀格式類似下面這樣: ![以太幀,圖片來自阮一峰部落格](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214829629-1979511199.png) 每臺網絡裝置都有自己的網絡卡,**乙太網是將資料從一塊[網絡卡](https://zh.wikipedia.org/wiki/網絡卡)傳送到另一塊網絡卡**,每塊網絡卡需要有自己的「身份證號」,叫 [MAC 地址](https://zh.wikipedia.org/wiki/MAC地址)(iPhone 手機的 MAC 地址叫無線區域網地址),由 12 個十六進位制數表示: > MAC地址:(**M**edia **A**ccess **C**ontrol Address),直譯為媒體存取控制位址,也稱為區域網地址(LAN Address),**乙太網地址**(Ethernet Address)或**實體地址**(Physical Address),它是一個用來確認網路裝置位置的地址。 所以乙太網傳送前需要知道接收方網絡卡的 MAC 地址,即標頭的接收方地址,但正常情況下,不知道接收方 MAC 地址,需要使用 [ARP 協議](https://zh.wikipedia.org/wiki/地址解析協議)得到(這個本文後面解釋) 假設已經知道了 MAC 地址,那麼在區域網內,乙太網可以根據 MAC 地址,將資料傳送給對方。但如果對方沒有在一個區域網內,如何傳送給對方呢?此時,就需要[網路層](https://zh.wikipedia.org/wiki/網路層)(Network Layer)出馬了! --- 乙太網在 Windows 中的體現: ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214829934-8129566.jpg) 在 macOS 的體現: [PPPoE](https://zh.wikipedia.org/wiki/PPPoE)(英語:**P**oint-to-**P**oint **P**rotocol **o**ver **E**thernet),乙太網上的點對點協議。 ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214830682-1383140791.jpg) ## 四、網路層(Network Layer) 首先,我們要區分接收方是否在一個區域網,使用 MAC 地址不能區分,需要裝置有另外一個地址,能代表它所處的具體是哪個網路(區域網),我們稱這個地址為「**網路地址**」。 **網路層的作用,就是根據網路地址找到目的主機處於哪一個區域網**。實現這一功能的協議稱為網路協議,即 [IP 協議](https://zh.wikipedia.org/wiki/網際協議) 。網路地址用於 IP 協議,所以網路地址也可以叫它 IP 地址。**注意**:我們叫 IP 協議,是一種習慣,其實 IP(**I**nternet **P**rotocol) 本身就有協議的意思。 如果裝置連 WiFi,路由器會為裝置分配一個 IP 地址。 ### 4.1 IP 協議 > **IP** 協議:英語全稱為:**I**nternet **P**rotocol,即**網路協議**,也稱**網際協議**。 現在大部分使用的還是 IP 協議第四版,簡稱 IPv4,IP 地址為 32 位(4*8,二進位制)。 ![圖片來自阮一峰部落格](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214830990-1191090675.png) 有了 IP 地址,網路層可以通過 IP 地址來區分是否處於一個區域網。如何根據 IP 地址判斷裝置是否處於同一個區域網?答案是利用[子網掩碼](https://zh.wikipedia.org/wiki/子網#網路掩碼)。IP 地址分為兩部分,網路部分和主機部分,如果子網掩碼為 `255.255.255.0`(二進位制表示:`11111111.11111111.11111111.00000000`),表示前 24 位代表網路部分,如果兩個 IP 地址前 24 位相同,則代表是在同一個區域網中。 ### 4.2 IP 資料包 資料經過網路層,IP 協議為資料加上包含傳送方 IP 地址和接收方 IP 地址的標頭,包裝為 IP 資料包: ![圖片來自阮一峰部落格](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214831186-1023728486.png) IP 資料包到達鏈路層時,直接作為作為以太幀的資料部分,嵌入以太幀。此時的以太幀的格式如下: ![圖片來自阮一峰部落格](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214831331-14202241.png) 如果通過子網掩碼判斷接收方在一個區域網,就通過乙太網傳送,此時需要得到其 MAC 地址,前面說,需要 ARP 協議得到其 MAC 地址,何為 ARP 協議? ### 4.3 ARP 協議 ARP 協議,英語全稱為:**A**ddress **R**esolution **P**rotocol,即地址解析協議,是一種通過 IP 地址得到 MAC 地址的協議。預設情況,傳送方知道接收方的 IP 地址(通過 [DNS](https://zh.wikipedia.org/wiki/域名系統) 得到,這個又後面解釋),所以傳送方使用「廣播」(broadcasting)的方式給當前區域網所有主機發送一個以太幀,包含對方的 IP 地址,對方 MAC 地址設為 `ff:ff:ff:ff:ff:ff`,接收方根據接收者 IP 地址判斷自己是否為接收者,是,就傳送一個數據包告訴對方自己的 MAC 地址,不是,就丟棄這個包。 通過這種方式,傳送方就可以通過接收方的 IP 地址得到 MAC 地址。 如果通過子網掩碼判斷接收方不在一個區域網,通過 APR 協議就得不到對方的 MAC 地址,那就要使用[路由](https://zh.wikipedia.org/wiki/路由)(Route)的方式傳送了。 ### 4.4 路由 路由,簡單來說,就是得到路由器的 MAC 地址,資料先發送到[路由器](https://zh.wikipedia.org/wiki/路由器)(Router),由路由器來發送下一個路由器,通過一系列路由中轉,最後發給目標主機。 其實就像傳送快遞一樣,在快遞上寫上收件人的地址,由快遞點發送給下一個中轉站,再中轉,最後收件人收到快遞。 ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214831869-1091316330.png) 一個簡單的路由器,需要實現 IP 協議和鏈路層協議。 如果把上面的過程說的仔細一點,乙太網是將以太幀傳送給路由器鏈路層,路由器鏈路層將資料包傳送給路由器網路層,路由器有一個路由表,網路層在路由表找到跟當前路由器相連的、離目的主機最近的路由器,路由器通過 ARP 協議,得到下一個路由器的 MAC 地址,讓路由器鏈路層根據 MAC 地址,傳送給下一個路由器。通過一系列中轉,來到目的主機所在的路由器。使用同樣的方式,通過乙太網將以太幀傳送給目的主機。整個過程大概是這樣: ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214832421-1655798048.png) 我們常說,網路層負責定址和路由,定址就是尋找最近的 IP 地址,路由就是找到最近的路由 MAC 地址(我這麼理解,不一定正確)。我們可以理解為:整個通訊過程中的網路層負責定址和路由,傳送方的網路層其實負責它自己的定址和路由。 ## 五、傳輸層(Transport Layer) 網路層和鏈路層實現了網際網路任意兩臺主機之間的網路通訊,此時還有兩個問題,**1、裝置不止一個程式,具體傳送給哪一個程式?2、沒有保證資料包能傳送成功。** 這時候就需要[傳輸層](https://zh.wikipedia.org/wiki/傳輸層)(Transport Layer),**傳輸層的功能是保證資料能可靠傳輸到對方主機的應用程式上。** 應用是程序,**每個程序使用網絡卡時,需要有一個編號,這個編號就是埠**。系統預設佔用 0 到 1023 的埠,系統會為軟體隨機分配 1024 到 65535 之間的埠。 常見術語套接字(Socket)就是 IP 地址 + 埠的組合稱謂。 傳輸層要為傳送的資料包中增加發送方和接收方的埠號。 傳輸層功能實現一般有兩種協議,1 是 [TCP 協議](https://zh.wikipedia.org/wiki/傳輸控制協議),2 是 [UDP 協議](https://zh.wikipedia.org/wiki/使用者資料報協議)。 ### 5.1 TCP 協議 > **TCP** 協議,英語全稱為:**T**ransmission **C**ontrol **P**rotocol,即,**傳輸控制協議** TCP 協議使用用三次握手來保證線路的可靠,失敗後,有失敗重傳機制,它是一個很複雜的協議,傳輸層的稱謂,也是來源於 TCP 這個 **傳輸控制協議**。 TCP 協議傳送的資料包叫 TCP 資料包,它的標頭包含傳送方埠和接收方埠, ![圖片來自阮一峰部落格](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214832604-1262352156.png) 它傳送資料包給網路層,網路層將 TCP 資料包作為 IP 資料包的資料部分,再發給鏈路層。此時以太幀格式如下: ![圖片來自阮一峰部落格](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214832760-724275638.png) 因為以太幀有長度限制,TCP 協議沒有規定資料的長度,所以當 TCP 資料包過長時,以太幀裝不下,此時 TCP 資料包需要切分為多個 TCP 資料包。我們常常看到有的書籍說:傳輸層負責「請求報文」的分割。這就是傳輸層為什麼要分割「請求報文」的緣故。 傳輸層保證資料的「可靠傳輸」,這句話常常被我們誤解為,是由傳輸層傳輸資料,現在我們知道,傳輸資料的其實是鏈路層,傳輸層其實只是失敗重傳(當然不止這一個功能,這裡這麼說是為了方便理解)。所以這句話的重點在於**可靠**,不在傳輸。 ### 5.2 UDP 協議 > **UDP 協議**,英語全稱為: **U**ser **D**atagram **P**rotocol,即**使用者資料包協議** 傳輸層有一種簡單的協議,叫 UDP 協議,UDP 協議只是為資料簡單的加上包含傳送方埠和接收方埠的標頭,就將 UDP 資料包扔給網路層,它不保證是否能成功的傳送給接收方,它是一種不可靠的傳輸協議。因為簡單,減少了時間開銷,常用於對時間有較高要求的應用程式。 ## 六、應用層(Application Layer) 鏈路層、網路層、傳輸層實現了資料包能從主機應用傳送到目的主機應用。正常情況下,網路上主要傳輸的資料是應用產生的。傳輸的資料各種各樣,有網路請求,有電子郵件等等。資料需要由[應用層](https://zh.wikipedia.org/wiki/應用層)(Application Layer)封裝,即規定資料的格式。 規定「網路請求資料」格式的是 [HTTP 協議](https://zh.wikipedia.org/wiki/超文字傳輸協議)。可以說,HTTP 協議是應用層的一種實現。 ### 6.1 HTTP 協議 > **HTTP 協議**:英文全稱為:H**yper**T**ext **T**ransfer **P**rotocol,即超文字轉移(傳輸)協議 當我們開啟百度首頁時,輸入的就是一個網址 `www.baidu.com`,這是一個 GET 請求,HTTP 協議將請求封裝為應用層資料包。這樣,百度的伺服器應用層就可以根據 HTTP 協議來解析資料包。 HTTP 請求的資料包一般稱為請求報文,分為報文首部和報文主題,報文首部即為請求頭,請求頭格式如下: ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214832995-1906529284.jpg) 包含的應用層資料包的以太幀格式如下: ![圖片來自阮一峰部落格](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214833157-647488711.png) ### 6.2 DNS > **DNS**:英語全稱為: **D**omain **N**ame **S**ystem,即**域名系統** 類似 `www.baidu.com` 這樣的網址域名,是為了使用者方便記憶,網路通訊時,需要將域名轉換為 IP 地址,這是由 [DNS](https://zh.wikipedia.org/wiki/域名系統) 負責的,它也屬於應用層。 ## 七、WireShark 抓包分析 當 Mac 連 WIFI 後,可以在「設定->網路」中看見下面這些內容: ![TCP/IP](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214833698-1942929917.jpg) ![MAC 地址](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214833982-767638251.jpg) ![DNS 地址](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214834199-934769607.jpg) 此時電腦,有自己的 IP 地址、MAC 地址、還知道路由器的 IP 地址、DNS 伺服器地址(由路由器負責域名解析,所以 DNS 地址其實就是 IP 地址)和當前的子網掩碼。還可以看出,路由器動態分配 IP 地址是由 [DHCP](https://zh.wikipedia.org/wiki/動態主機設定協議) 實現的。 通過開啟百度首頁,結合抓包工具 Wireshark 來看看網路通訊過程中的資料包的內容。 關於如何使用 Wireshark,請看 [使用 wireshark 學習網路協議](https://juejin.im/post/5c87059ae51d452f3f64b110)。通過 `ping www.baidu.com` 得到百度的 IP 地址為 `61.135.169.121`,在 Wireshark 中配置過濾條件後,通過使用命令 `curl www.baidu.com` 來模擬開啟百度首頁: ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214836386-362365619.jpg) 此時在 Wireshark 中可以看出,TCP 協議傳送了以太幀,以太幀的格式是:Ethernet II 標頭 + IP 4 標頭 + TCP 標頭 + TCP 資料,TCP 標頭顯示源埠為 53732,目的地埠為 80;IP 標頭顯示源 IP 地址為 `192.168.31.206`,目的地 IP 地址為 `61.135.169.121`;乙太網標頭顯示源 MAC 地址為 `f0:18:98:46:bf:65`,目的地 MAC 地址為 `28:6c:07:9d:e2:8e`(小米路由器地址)。幀的長度為 78 位元組,TCP 資料包的長度為 44 個位元組。 ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214837504-1197393727.jpg) 這與我們前面說的相符合,目的主機不在同一個區域網,通過乙太網傳送以太幀給路由器,再由路由器負責路由傳送。 前三個資料包為 TCP 的 3 次握手,接著傳送了 HTTP 資料包,HTTP 資料包包含了請求的內容: ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214838262-144315251.jpg)整個過程:先使用 TCP 協議完成了 3 次握手,然後使用 HTTP 協議傳送了 GET 請求,接收到了百度的 HTTP 響應,最後使用 TCP 協議完成了 4 次揮手。 ![](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214838775-1240222390.jpg) ## 八、總結 網際網路協議整個網路通訊過程可以用下面這張圖描述: ![圖片來自 Wiki](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214839313-942015146.png) 對於傳送方的資料處理,**這個過程像是一個俄羅斯套娃的過程**: ![圖片來自 Wiki](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214839930-702484959.png) 如果用發快遞來類比一下: ``` 應用層:將物體打包為快遞 | 傳輸層:為快遞填上收件人門牌號;如果快遞丟失重新發送 | 網路層:為快遞填上收件人小區地址;並根據收件人小區地址,找到下一個快遞中轉站的地址,最終找到整個線路 | 鏈路層:為快遞填上下一個中轉地地址;並負責將快遞發往到下一個中轉站 | 物理層:運快遞的車 ``` 在網際網路協議中,因為 TCP/IP 協議最重要,所以網際網路協議也可以叫做 「**TCP/IP 協議族**」。 此文只是個人對網際網路協議的淺顯理解,畢竟沒有深入研究,可能有諸多不當處,歡迎留言指出。 最後我想說一句,阮一峰牛逼。有的知識點是知道怎麼回事,就是不能正確的表達出來,遣詞排句真的很需要功力,真的需要常年累月的積累。 ## 九、延伸閱讀 - [網際網路協議入門(一)_阮一峰_](http://www.ruanyifeng.com/blog/2012/05/internet_protocol_suite_part_i.html) - [網際網路協議入門(二)_阮一峰_](http://www.ruanyifeng.com/blog/2012/06/internet_protocol_suite_part_ii.html) - [使用wireshark學習網路協議](https://juejin.im/post/5c87059ae51d452f3f64b110) ![個人公眾號](https://img2020.cnblogs.com/other/1191638/202003/1191638-20200320214840913-1274635