計算機網絡漫談

前言:

本文作於2017年1月~3月之間,藉助大三寒假的時間,我把自己學習的網絡相關的知識做了個簡單的整理,由於個人能力有限,我參考了 阮一峯 互聯網協議入門,並且在我文中出現的一些插圖也是來自他的原文,通過這些文章,我希望能讓讀者建立起計算機網絡的基本概念,但是文章中也有許多語焉不詳的地方,如果搞懂,我會不斷更新。

我希望你讀這些文章就像讀故事一樣,這樣你會很容易理解網絡中的一些諸如爲什麼計算機需要IP?沒有IP可以嗎?什麼是路由器?什麼是子網掩碼?什麼是MAC地址?TCP爲什麼是可靠傳輸?HTTP協議需要三次握手嗎?爲什麼它又是無狀態的?等問題。理解了這些問題之後,你或許會對你目前學習的Socket編程,Node.js,Nginx,Apache以及Web等知識有更深的理解。當然,你在看的過程中肯定會遇到一些問題,這時候我希望你能大膽評論。好了,我知道你已經迫不及待想往下看了,我們繼續^_^。

目錄列表

1:什麼是網絡

2:OSI七層模型和TCP/IP四層模型

3:數據鏈路層

4:網絡層

5:IP與子網掩碼

6:IP數據包

7:傳輸層

8:UDP和TCP

9:應用層

1:什麼是網絡

我提出一個問題:你的微信消息怎樣發送給你的好友?

或許你現在什麼也不知道?或許你現在已經可以告訴我:消息是先到騰訊的微信服務器的,然後騰訊再遍歷我的好友列表,找到好友,把消息發送給他。回答正確!但是也很明顯,這個過程中你和好友的手機都是和騰訊服務器相連的。

所以什麼是網絡呢?就是用物理設備將各個“局域網”相連組成的更大的“局域網”。小的局域網可以是家裏的WiFi,或者陝西省的網絡你也可以看作是一個局域網。物理設備就是網線、光纜等。你問:那美國和中國怎麼辦?答:海底有電纜你怕啥。你又問:我家和你家怎麼辦?答:假設你家是廣電的網,我家是電信的,你家用廣電的網線接到廣電的服務器上,我家同理接到電信的服務器上,它們兩個ISP(Internet Service Provider 互聯網服務提供商)肯定也是相連的,這不就能通信了嗎?下圖是2015年全球互聯網跨國通信光纜的連接情況。

這裏寫圖片描述

其中密密麻麻的線就是各個國家之間的連接情況。所以網絡沒有什麼神奇的,小到一臺手機,大到一個國家如果想在目前我們所熟知的“互聯網”上獲取或者共享信息,那它就必須以某種物理方式接入到互聯網。

當然,只把這些通信設備連在一起肯定不行,必須得有一些約定或者說規矩來告訴不同型號的設備、不同規格的網絡如何按照同樣的方法處理相同的數據、網絡上誰是誰?這就是網絡協議了。早期的計算機網絡,都是由各廠商自己規定一套協議,IBM,Apple,和MicroSoft都有自己的網絡協議,比如IBM的兩臺電腦用網線連起來,互相說話能聽懂。但是IBM和Apple的電腦連接起來說話就聽不懂了,想想你和我微信聊天,我是IBM電腦,你是Apple電腦,你發送的消息到我這裏顯示不了或者解析成另一個意思,你說多坑。爲了把全世界的所有不同類型的計算機都連接起來,就必須規定一套全球通用的協議,爲了實現這個目標,互聯網協議簇(Internet Protocol Suite)就成爲了通用協議標準。

Internet是由inter和net兩個單詞組合起來的,原意就是連接“網絡”的網絡,有了Internet,任何私有網絡,只要支持這個協議,就可以聯入互聯網。互聯網協議包含了上百種協議,但是最重要的兩個協議是TCP和IP協議,而我們通常把基於TCP和IP協議的所有協議統稱爲”TCP/IP協議(蔟)”。因此,計算機網絡說白了就是物理連接的“局域網”和工作於這個局域網上的“網絡協議”,我們接下來會把重點放在討論“網絡協議”上面.

2:OSI七層模型和TCP/IP四層模型

什麼是網絡? 中,你已經知道計算機網絡是物理連接的“局域網”和工作於這個局域網上的“網絡協議”,並且我們的重心是網絡協議。有關網絡協議,按照目前的分層方式主要有兩種,一種是OSI七層模型(忽略它,沒什麼卵用 :)),一種是TCP/IP四層模型。下面我們主要來看看它們的對應關係和工作在不同層的具體協議。

OSI TCP/IP 常見網絡協議
應用層(Application) 應用層

HTTP(超文本傳輸協議)

FTP(文件傳輸協議)

DNS(域名系統)

表示層(Represent)
會話層(Conversation)
傳輸層(Transport) 傳輸層

TCP(傳輸控制協議)

UDP(用戶數據報協議)

網絡層(Internet) 網絡層

IP(網絡協議)

ICMP(網絡控制消息協議)

數據鏈路層(DataLink) 數據鏈路層

ARP(地址解析協議)

RARP(反向地址解析協議)

物理層(Physical)


請再看一次上面的圖片,確保你記住了每層對應的網絡協議。現在你可能還有疑問:爲什麼要分層呢?答:說白了就是因爲在網絡傳輸中,所需要解決的問題不是同一個類型的或者層次的,比如要實現傳遞可靠數據(傳輸層),先要實現能傳遞數據(網絡層),那最起碼需要實現兩臺電腦之間能發數據包(數據鏈路層)。所以分層的解決方式無疑成爲了首選,每一層都有自己需要解決的問題,下層協議爲上層協議提供幫助。就像工廠的流水線一樣,從最初的產品 -> 紙袋包裝 ->禮品盒包裝 ,而對面打開的次序剛好是相反的(數據包的拆包亦是如此)。下面我們要從協議最底部出發,沿着 數據鏈路層->網絡層->傳輸層->應用層 的順序依次分析這些協議。

3:數據鏈路層

讓我們從整個協議最底層開始,先來看看數據鏈路層主要都做了哪些事:

這裏寫圖片描述

首先上面兩臺電腦需要通信,先將它們物理連接起來,然後就可以傳送高低電位了,高電位表示1,低電位表示0。但是單純的0和1沒有任何的意義,我們必須人爲的規定解讀方式,比如:多少個0和1作爲一組信號?每個信號位有什麼含義?……

還記得不?我們前面說過互聯網早期的時候好多公司都有自己的網絡協議。但是最後逐漸被“以太網”佔據了主導地位,以太網規定,一組電信號構成一個數據包,叫做“幀”。每一幀分爲兩個部分:標頭(Head)和數據(Data)。

這裏寫圖片描述

“標頭”包含數據包的一些說明項,比如發送者(源物理地址)、接受者(目的物理地址)、數據類型、CRC校驗碼等等。”數據”則是數據包的具體內容。具體的幀結構如下圖所示:

這裏寫圖片描述

“標頭”的長度,固定爲18字節(6+6+2+4=18)。”數據”的長度,最短爲46字節,最長爲1500字節(MTU Maximum Transmission Unit 最大傳輸單元)。因此,整個”幀”最短爲64字節,最長爲1518字節。如果數據很長,就必須分割成多個幀進行發送。你可以使用ifconfig命令來查看自己網卡的MTU,下圖是我的網卡情況。

這裏寫圖片描述

從上面“幀”的結構中可以看到,“標頭”包含了“源物理地址”和“目的物理地址”,其實這就是我們常說的MAC地址。以太網規定,連入網絡的所有設備,都必須具有”網卡”接口。數據包必須是從一塊網卡,傳送到另一塊網卡。網卡的地址,就是數據包的發送地址和接收地址,這叫做MAC地址。

這裏寫圖片描述

每塊網卡出廠的時候,都有一個全世界獨一無二的MAC地址,長度是48個二進制位,通常用12個十六進制數表示。前6個十六進制數是廠商編號,後6個是該廠商的網卡流水號。有了MAC地址,就可以定位網卡和數據包的路徑了。(同樣,ifconfig命令就可以查看網卡的MAC地址,上張截圖中有我的網卡MAC地址,你找找看)

這裏寫圖片描述

當然,現在有了地址也只是第一步,可是我的網卡怎麼會知道你網卡的MAC地址呢?
答:有一種ARP協議,可以解決這個問題。這個留到後面再說,這裏只需要知道,以太網數據包必須知道接收方的MAC地址,然後才能發送。
其次,就算有了MAC地址,系統怎樣才能把數據包準確送到接收方?
答:以太網採用了一種很”原始”的方式,它不是把數據包準確送到接收方,而是向本網絡內所有計算機發送,讓每臺計算機自己判斷,是否爲接收方。

這裏寫圖片描述

上圖中,1號計算機向2號計算機發送一個數據包,同一個子網絡的3號、4號、5號計算機都會收到這個包。它們讀取這個包的”標頭”,找到接收方的MAC地址,然後與自身的MAC地址相比較,如果兩者相同,就接受這個包,做進一步處理,否則就丟棄這個包。這種發送方式就叫做”廣播”(broadcasting)。

現在,我們假設全球的電腦都是用網線直接相連的,那有了數據包的定義(幀)、網卡的MAC地址、廣播的發送方式。只要知道目的MAC地址我們就可以實現給世界各地任何電腦發送數據了。比如A可以直接廣播B網卡的MAC地址大膽表白,發送“我愛B”,然後全球所有的網卡都會收到這條消息,但是隻有B的網卡纔會接受這條消息,也就是“我只愛B”,是不是很浪漫,沒毛病。

好,回過頭來看看,我們現在已經從兩臺網線直接相連的電腦發展到全球電腦都能通信了,真棒!那請你思考下廣播的這種方式到底合適嗎?請將自己的想法評論在下面。

4:網絡層

數據鏈路層 中,我們Get了數據包的定義(幀=標頭+數據)、網卡的MAC地址、廣播發送方式三個重要概念。並且我們知道在技術上,依靠MAC地址和廣播的發送的方式,我們其實可以實現全世界範圍內的計算機互相通信(比如西安和芝加哥)。留給你的問題是:廣播的方式到底合適嗎?回答:不能適用一般數據包的發送,會給網絡造成很大的壓力,是資源的浪費。就是這樣,世界上這麼多計算機,兩兩通信如果所有人都會收到,網絡上的數據量將是不可估計的,會造成災難。

實際上呢,目前的互聯網在設計的時候,廣播的方式是侷限在發送者所在的子網絡的。互聯網是無數子網絡共同組成的一個巨型網絡,很難想象西安和芝加哥的電腦會在同一個子網絡,這是不可能的。如下圖是互聯網的組成情況,想想我們之前對網絡的定義:由多個局域網相連組成的,下面的子網絡也就是局域網。

這裏寫圖片描述

因此,必須找到一種方法,能夠區分哪些MAC地址屬於同一個子網絡,哪些不是。如果是同一個子網絡,就採用廣播方式發送,否則就採用”路由”方式發送。(”路由”的意思,就是指如何向不同的子網絡分發數據包,這是路由器乾的活,我們先不涉及)遺憾的是,MAC地址本身無法做到這一點。它只與廠商有關,與所處網絡無關。

這就導致了”網絡層”的誕生。它的作用是引進一套新的地址,使得我們能夠區分不同的計算機是否屬於同一個子網絡。這套地址就叫做”網絡地址”,簡稱”網址”

於是,”網絡層”出現以後,每臺計算機有了兩種地址,一種是MAC地址,另一種是網絡地址。兩種地址之間沒有任何聯繫,MAC地址是綁定在網卡上的,網絡地址則是管理員分配的,它們只是隨機組合在一起(因此網址可以變化)。

網絡地址幫助我們確定計算機所在的子網絡,MAC地址則將數據包送到該子網絡中的目標網卡。因此,從邏輯上可以推斷,必定是先處理網絡地址,然後再處理MAC地址。

規定網絡地址的協議,叫做IP協議。它所定義的地址,就被稱爲IP地址。

目前,廣泛採用的是IP協議第四版,簡稱IPv4。這個版本規定,網絡地址由32個二進制位組成。

這裏寫圖片描述

我們習慣用分成四段的十進制數表示IP地址,從0.0.0.0一直到255.255.255.255。
互聯網上的每一臺計算機,都會分配到一個IP地址。這個地址分成兩個部分,前一部分代表網絡,後一部分代表主機。比如,IP地址172.16.254.1,這是一個32位的地址,假定它的網絡部分是前24位(172.16.254),那麼主機部分就是後8位(最後的那個1)。處於同一個子網絡的電腦,它們IP地址的網絡部分必定是相同的,也就是說172.16.254.2應該與172.16.254.1處在同一個子網絡。

5:IP與子網掩碼

通過之前的介紹,我們現在已有的概念是任何一臺計算機如果需要接入互聯網,都會分配到一個IP地址。這個地址分成兩個部分,前一部分代表網絡,後一部分代表主機。比如,IP地址172.16.254.1,這是一個32位的地址,假定它的網絡部分是前24位(172.16.254),那麼主機部分就是後8位(最後的那個1)。因此,處於同一個子網絡的電腦,它們IP地址的網絡部分必定是相同的,也就是說172.16.254.2應該與172.16.254.1處在同一個子網絡(它們的網絡號相同:172.16.254)。

但是,問題在於單單從IP地址,我們無法判斷網絡部分。還是以172.16.254.1爲例,它的網絡部分,到底是前24位,還是前16位,甚至前28位,從IP地址上是看不出來的。 那麼,怎樣才能從IP地址,判斷兩臺計算機是否屬於同一個子網絡呢?這就要用到另一個參數”子網掩碼”(subnet mask)。

所謂”子網掩碼”,就是表示子網絡特徵的一個參數。它在形式上等同於IP地址,也是一個32位二進制數字,它的網絡部分全部爲1,主機部分全部爲0。比如,IP地址172.16.254.1,如果已知網絡部分是前24位,主機部分是後8位,那麼子網絡掩碼就是11111111.11111111.11111111.00000000,寫成十進制就是255.255.255.0

知道”子網掩碼”,我們就能判斷,任意兩個IP地址是否處在同一個子網絡。方法是將兩個IP地址與子網掩碼分別進行AND運算(兩個數位都爲1,運算結果爲1,否則爲0),然後比較結果是否相同,如果是的話,就表明它們在同一個子網絡中,否則就不是。

比如,已知IP地址172.16.254.1和172.16.254.233的子網掩碼都是255.255.255.0,請問它們是否在同一個子網絡?
答:兩者與子網掩碼分別進行AND運算,結果都是172.16.254.0,因此它們在同一個子網絡。

我們總結一下IP協議的主要作用:一個是爲每一臺計算機分配IP地址,另一個是確定哪些地址在同一個子網絡

6:IP數據包

網絡層從 網絡層IP與子網掩碼 前前後後我們也說了兩次了,IP 這個東西絮絮叨叨的也一直在提。今天我們來解開IP協議的面紗,還記得我們之前在數據鏈路層說的物理幀的結構嗎?就是這樣:

這裏寫圖片描述

其中Head叫標頭,包含源和目的MAC地址,那時我們還沒有IP的概念,但是我們用廣播的方式也已經能實現全世界範圍的通信,但之後我們否定了這種方式,因爲會造成網絡擁堵,浪費資源。因此就有了子網絡,自此,MAC地址和IP地址就隨機的結合在了一起,網絡通信發送的數據包中也就有了IP地址。但是上面說的幀頭部(Head)中只包含MAC地址,並沒有IP地址的欄位,那麼是否需要修改數據定義,再添加一個欄位呢?

回答是不需要,我們可以把IP數據包直接放進以太網數據包的”數據”部分,因此完全不用修改數據鏈路層幀的結構。這就是互聯網分層結構的好處:上層的變動完全不涉及下層的結構。我們先來說IP數據包,具體來說,IP數據包也分爲”標頭”和”數據”兩個部分。

這裏寫圖片描述

“標頭”部分主要包括版本、長度、IP地址等信息,”數據”部分則是IP數據包的具體內容。IP數據包的”標頭”部分的長度爲20到60字節(下次我們仔細研究),整個數據包的總長度最大爲65,535字節。因此,理論上,一個IP數據包的”數據”部分,最長爲65,515(65,535-20)字節。前面說過,以太網數據包的”數據”部分,最長只有1500(MTU)字節。因此,如果IP數據包超過了1500字節,它就需要分割成幾個以太網數據包,分開發送了。我們將它放進以太網數據包後,以太網數據包就變成了下面這樣。

這裏寫圖片描述

上面紅色的是網絡層的IP數據包,它又作爲了數據鏈路層“幀”的數據部分。是不是就能感受到這種從上向下逐層包裝的意思,上層的數據包作爲下層的數據部分,下層加入自己的包頭組成自己本層完整的數據包。再往下層傳遞又作爲下層的數據包,直到數據鏈路層的幀,最後被轉換成高低電位發送。下面我們研究下IP數據包的包頭,如圖:

這裏寫圖片描述

來看看每個字段的具體含義:

  • 版本號 佔4位,指IP協議的版本。IPv4的值爲 4
  • 頭部長度 佔4位,標識有多少個32bit字(4字節),4位最大爲1111,能表示15,因此IP頭部最長爲15*4=60字節。
  • 服務類型 佔8位,可以設置不同的服務功能,例如小延遲和大吞吐量。
  • 數據報總長度 總長度指首部和數據之和的長度,單位爲字節。總長度字段爲16位,因此數據報的最大長度爲2^16-1=65535字節。
  • 序列號 佔16位。能唯一標識主機發送的每一個數據報。
  • 分片標誌 三個bit位。第一位保留,未使用。第二位是DF(Don’t Fragment),如果爲1,表示未發生分片。第三位是MF(More Fragment),如果爲1,表示發生了分片,並且除了分片出的最後一個報文中此標誌爲0,其餘報文中此標誌均爲1。
  • 偏移量 佔13位。分片相對於原始IP數據報開始處的偏移。
  • 生存時間 佔8位,生存時間字段常用的的英文縮寫是TTL(Time To Live),表明是數據報在網絡中的壽命。每經過一個路由器時,就把 TTL值減1。當TTL值爲0時,就丟棄這個數據報。
  • 上層協議 佔8位,協議字段指出此數據報攜帶的數據是使用何種上層協議,以便使目的主機的IP層知道應將數據部分上交給上層哪個處理過程。
  • 首部檢驗和 佔16位。由發送端填充,接收端對其CRC檢驗以確定頭部是否損壞。
  • 源IP地址  佔32位。標識源IP。
  • 目的IP地址 佔32位。標識目的IP。

可以看到IP數據包頭部還有許多除過IP之外的字段,他們一起配合才實現了網絡層的重要功能。

7:傳輸層

之前我們通過學習 數據鏈路層網絡層 知道了一個計算機有兩個地址:MAC地址和IP地址,有了MAC地址和IP地址,我們已經可以在互聯網上任意兩臺主機上建立通信。

現在面臨的問題是,同一臺主機上有許多程序都需要用到網絡。比如,你一邊瀏覽網頁,一邊與我QQ聊天。當一個數據包從互聯網上發到你電腦的時候,它怎麼知道,這是表示網頁的內容,還是表示聊天的內容?

也就是說,我們還需要一個參數,表示這個數據包到底供哪個程序(進程)使用。是瀏覽器呢還是QQ?這個參數就叫做”端口”(PORT),它其實是每一個使用網卡的程序的編號。每個數據包都發到主機的特定端口(比如瀏覽器就監聽80端口),所以不同的程序就能取到自己所需要的數據。

“端口”是0到65535之間的一個整數,正好16個二進制位。不管是瀏覽網頁還是QQ聊天,應用程序會隨機選用一個本地端口,然後與服務器的相應端口聯繫。

“傳輸層”的功能,就是建立”端口到端口”的通信(PORT)。相比之下,”網絡層”的功能是建立”主機到主機”的通信(IP)

8:UDP和TCP

計算機網絡漫談之傳輸層 咱們討論瞭如果需要確定一個計算機上的不同網絡程序(比如QQ和瀏覽器),需要端口的標識,但是IP頭部和幀的頭部都沒有端口的標識字段,需要新的協議。和前面IP協議的實現套路一樣,我們需要一個空間來存放端口號,因此就有了傳輸層的協議TCP和UDP。最簡單的實現就是UDP協議,它的格式幾乎就是在數據前面,加上端口號。UDP數據包,也是由”標頭”和”數據”兩部分組成。

這裏寫圖片描述

“標頭”部分主要定義了源端口和接收端口,”數據”部分就是具體的內容。具體的Head結構如下所示:
這裏寫圖片描述

然後,把整個UDP數據包放入IP數據包的”數據”部分,而前面說過,IP數據包又是放在以太網數據包之中的,所以整個以太網數據包現在變成了下面這樣:

這裏寫圖片描述

目前我們的數據包更加完善了,也更加能體現層層封裝的意思。綠色頭部是UDP頭部,紅色頭部是IP頭部,藍色頭部是幀的頭部,”上層標頭+數據”作爲下層的數據。

UDP協議的優點是比較簡單(它的數據包包頭幾乎只有端口和長度),容易實現,但是缺點是可靠性較差,一旦數據包發出,無法知道對方是否收到。爲了解決這個問題,提高網絡可靠性,TCP協議就誕生了。這個協議非常複雜,但可以近似認爲,它就是有確認機制的UDP協議,每發出一個數據包都要求確認。如果有一個數據包遺失,就收不到確認,發出方就知道有必要重發這個數據包了。

因此,TCP協議能夠確保數據不會遺失。它的缺點是過程複雜(TCP三次握手、四次揮手等)、實現困難(數據重傳機制、流量控制機制等)、消耗較多的資源。TCP數據包和UDP數據包一樣,都是內嵌在IP數據包的”數據”部分。TCP數據包也是由“標頭”和“數據”組成的。當然,“標頭”是重點。下面我們一起來看看TCP數據包的“標頭”:

這裏寫圖片描述

明顯比UDP的數據包“標頭”複雜多了,我們下面來依次解釋每個字段的含義。我儘量以最簡單的方式來解釋每個字段,目前你大概知道是幹什麼的就行了:

  • 源端口與目的端口: 各佔16位,分別寫入源端口號和目的端口號。
  • 32位序列號: 佔32位,能唯一標識一次通信中的數據包序號,可以看作是一個數據包的ID。
  • 32位確認序列號: 佔32位,作爲確認收到使用,比如如果想確定上面32位序列號,就把此值填爲其值加1。
  • 首部長度: 佔4位.表示整個“標頭”的長度,所以TCP報頭最大爲60字節。
  • URG: 佔1位,緊急指針標誌位,當URG=1時,表明緊急指針字段有效.它告訴系統中有緊急數據,應當儘快傳送,這時不會按照原來的排隊序列來傳送.而會將緊急數據插入到本報文段數據的最前面。
  • ACK: 佔1位,當ACK=1時,確認序列號纔有效,當ACK=0時,確認序號ack無效。
  • PSH: 佔1位,推送操作,很少用,沒有了解。
  • RST: 佔1位,當RST=1時,表明TCP連接出現嚴重錯誤,此時必須釋放連接。 (9)SYN: 佔1位,請求連接的標誌。
  • FIN: 佔1位,釋放鏈接的標誌.
  • 16位窗口的大小:佔16位,表示期望對方發送的字節數。
  • 16位檢驗和: 佔16位,用於檢驗包數據是否正確。
  • 緊急指針: 佔16位,只有當URG=1時的時候,緊急指針纔有效,它指出緊急數據的字節數。

9:應用層

有關網絡我們討論到今天,整個網絡框架我們已經搭建起來了。我們說了數據鏈路層網絡層傳輸層,其實應用層就是在我們之前討論的基礎上使用下面這些層,我打算舉例HTTP協議,也是應用層非常重要的協議,”應用層”的作用,就是規定應用程序的數據格式。比如HTTP協議的數據包基本如下所示:

這裏寫圖片描述

HTTP協議的職責就是把數據組織成這個樣子,然後把自己填入TCP數據包的”數據”部分。因此,現在的以太網的數據包就變成下面這樣,Data其實就是上面的HTTP格式字符串。

這裏寫圖片描述

是不是挺好理解的,逐層向下包裝完數據,然後發送。對方收到數據逐層向上拆包,之後就拿到了HTTP的數據包,然後讀取數據就成了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章