網路層主要是定義網路地址和路由尋徑,IP 是網路層的實現。
IP 地址
TCP/IP 協議網路上每一個網路介面卡都有一個 IP 地址。該地址由 32 bit 來定義,通常我們分為 8 bit*4 的格式分為 4 段,每一段又以十進位制的格式來顯示,如:192.168.0.1。
IP 地址分類
IP 地址分為兩部分:網路 ID(network id)和主機 ID (host ID)。
但是具體 32 bit 中哪部分表示網路 ID,哪部分表示主機 ID 並沒有強制規定。有些網路中主機數較多,那麼主機 ID 所佔的位數就多,反之亦然。
一般地,IP 地址分為分為以下幾類:
- A 類:IP 地址前 8 bit 表示網路 ID,後 24 bit 表示主機 ID,且二進位制 IP 地址以 0 開頭;
- B 類:IP 地址前 16 bit 表示網路 ID,後 16 bit 表示主機 ID,且二進位制 IP 地址以 10 開頭;
- C 類:IP 地址前 24 bit 表示網路 ID,後 8 bit 表示主機 ID,且二進位制 IP 地址以 110 開頭;
注意:
- IP 地址第一段大於 223 的屬於 D 類和 E 類地址,比較特殊,不做介紹;
- 若主機 ID 全為 0,則該 IP 代表網路本身,如 192.10.0.1 代表 192.10.0 這一個 C 類地址網路;
- 若主機 ID 全為 1,代表著廣播地址,用於向該網路中所有主機傳送訊息的,如 192.10.0.255 是網路 ID 為 192.10.0 網路的廣播地址。
- A 類地址中,整個 127 網路都是環回(loopback)地址,用以測試 TCP/IP 是否正常
PS: IP 地址由美國國防資料網 DDN 的網路資訊中心 NIC 進行分配。
子網
子網 ID
比如一個 A 類網路,下面可以有 2^24 > 1600w 臺主機,控制起來十分靈活,我們想要將該網路切分為更小的網路來調控,子網就是為了解決這種問題的。
我們上面提到,我們將一個 IP 地址分為網路 ID 和 主機 ID 兩部分,如果需要使用子網,則需要子網 ID(subnet id),它會佔用主機 ID 的空間。
簡單地舉個例子,比如學校分配到了一個 C 類網路 192.10.10.0,其網路 ID 即為 192.10.10,機主 ID 為 8 bit,共可容納 2^8 - 2 = 254 臺主機。現在我們將 IP 地址分為兩個子網,一個給教學區用,一個給辦公區用。有人說了,你直接再搞一個 C 類網路不就好了比如 192.10.11.0?這確實方便,但是這將造成 IP 地址的極大浪費。
子網掩碼
我們可以利用子網 IP,將學校網路切分為 2 個子網。這裡為了方便下面說明,先介紹一下**子網掩碼(subnet mask)**的概念。
子網掩碼跟 IP 地址一樣,也是 32 bit 來表示的,它含有連續的 1 和 0,而且一定是 1 排在前面。其中 1 表示的是已經切分出子網的網路 ID,0 表示的是主機 ID。
這麼說有點抽象,我們舉個例子吧。比如一個 C 類網路,193.10.10.0,我們可以將其想象成整個大網路其中的一個子網,它的網路 ID 為 24 bit,那麼其子網掩碼就為 255.255.255.0,表示為 193.10.10.0/24。
子網切分
現在,我們現在將學校網路切分為兩個子網,子網 ID 需要佔用 2 bit(至於為什麼不是 1 bit 下一段會講) 的主機 ID 位,此時可以將當前網路切分為 2 個子網(為什麼是 2 個子網而不是 4 個子網,下面也會說到)。
那麼此時切分出來的兩位子網的資訊如下:
網路 | 網路地址 | 廣播地址 |
---|---|---|
192.10.10.128/26 | 192.10.10.128 | 192.10.10.191 |
192.10.10.64/26 | 192.10.10.64 | 192.10.10.127 |
需要對上面的結果解釋一下。
首先,為什麼 2 bit 的子網 ID 只能切分出 2 個子網,不應該有 00,01,10,11 四種情況四個子網嗎?確實是,但是一般全 0 和全 1 的子網 ID 是不可用的,所以只剩下 01,10 兩種情況了(具體可見這篇文章)。
既然只有 01,10 兩種情況,那麼此時將 192.10.10.0 這個網路切分為:192.10.10.01000000 和 192.10.10.10000000 這兩個子網,為了看得更清晰我把最後 8 bit 寫成二進位制並且把子網 ID 加粗顯示。
對於這兩個子網,其主機 ID 位數就剩下 6 bit 了,將主機 ID 為全置 0 則對應子網的網路地址,全置 1 則對應子網的廣播地址。
ARP 協議
IP地址只是主機在網路層中的地址,若要將網路層中傳送的資料包交給目的主機,必須知道該主機的 MAC 地址。ARP,地址解析協議,就是將 IP 地址對映為 MAC 地址;反之有個 RARP 協議,是將MAC 地址對映為 IP 地址。
link: MAC地址
IP 路由
說了這麼多,那麼在網路層上,主機之間是如何通訊的?
考慮兩種情況:網段內通訊和不同網段(網路)間通訊。
網段內通訊
獲取目標 MAC 地址
比如上圖的主機 A 和 伺服器 A 都處於 192.168.0.0 網路中,主機 A 若想要傳送資料給伺服器 A,此時主機 A 知道自己的 IP 地址和 MAC 地址,同時還知道伺服器 A 的 IP 地址,但是不知道它的 MAC 地址。
這時,主機 A 通過子網掩碼計算出源地址(主機 A 的 IP 地址)和目標地址(伺服器 A 的 IP 地址)是處於同個網段內,那麼此時主機 A 就向本網段傳送一個 ARP 請求,該請求包中所帶的關鍵資訊如下:
傳送方IP地址:192.168.0.2 | 傳送方MAC地址:XX-XX-XX-XX-XX-XX
接收方IP地址:192.168.0.3 | 接收方MAC地址:FF-FF-FF-FF-FF-FF
複製程式碼
包中除 接收方 MAC 地址外,所有資訊都是未知的,接收方 MAC 地址設為廣播 MAC 地址。
這個 ARP 包在整個網段內都可以接收到,伺服器 A 自然也能接收到。伺服器 A 接收到後發現接收方 IP 是自己的 IP,那麼就將自己的 MAC 地址填上去並返回完整的 ARP 迴應包:
傳送方IP地址:192.168.0.2 | 傳送方MAC地址:XX-XX-XX-XX-XX-XX
接收方IP地址:192.168.0.3 | 接收方MAC地址:YY-YY-YY-YY-YY-YY
複製程式碼
現在,主機 A 就獲取到源 IP,源 MAC,目標 IP 和目標 MAC 了。此時再將這些資訊和一開始的資料包封裝在一起就可以傳送出去了。
ARP 快取
實際上,每臺主機都有維護一份 ARP 快取表,記錄著與自己發生過通訊的所有的直接相鄰裝置或主機的 MAC 地址,但ARP快取表經過一段時間會自動刪除。
這個過程其實就有點像寫信,比如說李雷想向班裡的一個人寫信。
- 李雷的名字(IP)和地址(MAC)自己肯定是知道的,家就住北京市奶子房吧。
- 你同學的名字(IP)叫韓梅梅他肯定也知道,但是不知道她家(MAC)住哪兒。
- 這時李雷就在班裡的 QQ 群喊了一句:“韓梅梅,我叫李雷,家住北京奶子房,你家地址是什麼?”(ARP 包)
- 這時候班裡所有人肯定都收到這條訊息,但是他們想:“不又是叫我名字,不鳥他。”只有韓梅梅迴應:“家住北京五道口的李雷,我是韓梅梅,我家住在北京南站東廣場西出口~”(ARP 迴應包)
- 然後班裡所有人肯定又都收到這條訊息,但是他們想:“不又是叫我名字,不鳥他。”只有李雷默默地記下了她的地址。
- 然後李雷就能成功把寄信人、寄信地址、收件人和收件地址給寫全了,然後把包裹在信封裡面的信寄出去了。
- 下次李雷想寫信給韓梅梅的時候,就不用再次去詢問韓梅梅的地址了,因為他還記得上次寫信時的地址(ARP快取表),但是如果太久沒寫信,李雷就健忘了,還是得問韓梅梅家住哪兒。
- md,李雷真矯情,都用 QQ 了還寫信,去 QQ 愛啊淦。
不同網段通訊
不同網段間裝置的通訊就要依賴路由器了。
比如說主機 A 想要傳送資料給主機 B,用子網掩碼算了一下,兩者並不屬於同個網路。也就是說主機 A 不知道要發給誰了,這種情況會預設傳送到閘道器,傳送到閘道器之前當然也需要知道閘道器的 MAC 地址,閘道器的 IP 是知道的(192.168.0.1),閘道器 MAC 的獲取方法就跟上面的例子一樣。
得到閘道器的 MAC 地址後,我們就可以將資料包傳送出去了,但是注意,此時的目標 IP 是主機 B 的 IP,但是目標 MAC 是閘道器 MAC。
源IP:主機A的IP | 源MAC:主機A的MAC | 目標IP:主機B的IP | 目標MAC:路由器X介面MAC | 資料
複製程式碼
圖中我們假設閘道器本身是路由器,如果閘道器是一臺普通的 PC,那麼需要將資料發給路由器處理。路由器接收到資料包後發現,Y 埠和目標 IP 處於同個網段,這時通過 ARP 來確定目標 IP 的 MAC 地址,重新修改資料包中目標 MAC 地址和源 MAC 地址即可。(注意源 MAC 和目標 MAC 在不同網段的通訊過程中是會一直改變的)
源IP:主機A的IP | 源MAC:路由器Y介面MAC | 目標IP:主機B的IP | 目標MAC:主機B的MAC | 資料
複製程式碼
當然,這種網路介面是很簡單的,只需要一個路由就可以實現兩個不同網路間的通訊(這種路由稱直接路由),而實際情況下,資料包可能需要經過很多個路由才能達到目標主機。