我把本身以往的文章彙總成爲了 Github ,歡迎各位大佬 star
https://github.com/crisxuan/bestJavaerhtml
前面咱們學習了運輸層如何爲客戶端和服務器輸送數據的,提供進程端到端的通訊。那麼下面咱們將學習網絡層其實是怎樣實現主機到主機的通訊服務的。幾乎每一個端系統都有網絡層這一部分。因此,網絡層必然是很複雜的。下面我將花費大量篇幅來介紹一下計算機網絡層的知識。git
網絡層是 OSI 參考模型的第三層,它位於傳輸層和鏈路層之間,網絡層的主要目的是實現兩個端系統之間透明的數據傳輸。程序員
網絡層的做用從表面看上去很是簡單,即將分組
從一臺主機移動到另一臺主機。爲了實現這個功能,網絡層須要兩種功能github
轉發
:由於在互聯網中有不少路由器
的存在,而路由器是構成互聯網的根本,路由器最重要的一個功能就是分組轉發
,當一個分組到達某路由器的一條輸入鏈路時,該路由器會將分組移動到適當的輸出鏈路。轉發是在數據平面中實現的惟一功能。在網絡中存在兩種平面的選擇面試
- 數據平面(data plane):負責轉發網絡流量,如路由器交換機中的轉發表(咱們後面會說)。
- 控制平面(control plane):控制網絡的行爲,好比網絡路徑的選擇。
路由選擇
:當分組由發送方流向接收方時,網絡層必須選擇這些分組的路徑。計算這些路徑選擇的算法被稱爲 路由選擇算法(routing algorithm)
。也就是說,轉發是指將分組從一個輸入鏈路轉移到適當輸出鏈路接口的路由器本地動做。而路由選擇是指肯定分組從源到目的地所定位的路徑的選擇。咱們後面會常常提到轉發和路由選擇這兩個名詞。算法
那麼此處就有一個問題,路由器怎麼知道有哪些路徑能夠選擇呢?後端
每臺路由器都有一個關鍵的概念就是 轉發表(forwarding table)
。路由器經過檢查數據包標頭中字段的值,來定位轉發表中的項來實現轉發。標頭中的值即對應着轉發表中的值,這個值指出了分組將被轉發的路由器輸出鏈路。以下圖所示緩存
上圖中有一個 1001 分組到達路由器後,首先會在轉發表中進行索引,而後由路由選擇算法決定分組要走的路徑。每臺路由器都有兩種功能:轉發和路由選擇。下 面咱們就來聊一聊路由器的工做原理。安全
下面是一個路由器體系結構圖,路由器主要是由 4 個組件構成的服務器
輸入端口(input port)
有不少功能。線路終端功能
和數據鏈路處理
功能,這兩個功能實現了路由器的單個輸入鏈路相關聯的物理層和數據鏈路層。輸入端口查找/轉發功能
對路由器的交換功能來講相當重要,由路由器的交換結構來決定輸出端口,具體來說應該是查詢轉發表來肯定的。交換結構(Switching fabric)
就是將路由器的輸入端口鏈接到它的輸出端口。這種交換結構至關因而路由器內部的網絡。輸出端口(Output ports)
經過交換結構轉發分組,並經過物理層和數據鏈路層的功能傳輸分組,所以,輸出端口做爲輸入端口執行反向數據連接和物理層功能。路由選擇處理器(Routing processor)
在路由器內執行路由協議,維護路由表並執行網絡管理功能。上面只是這幾個組件的簡單介紹,其實這幾個組件的組成並不像描述的那樣簡單,下面咱們就來深刻聊一聊這幾個組件。
上面介紹了輸入端口有不少功能,包括線路終端、數據處理、查找轉發,其實這些功能在輸入端口的內部有相應的模塊,輸入端口的內部實現以下圖所示
每一個輸入端口中都有一個路由處理器維護的路由表的副本,根據路由處理器進行更新。這個路由表的副本能 夠使每一個輸入端口進行切換,而無需通過路由處理器統一處理。這是一種分散式
的切換,這種方式避免了路 由選擇器統一處理形成轉發瓶頸。
在輸入端口處理能力有限的路由器中,輸入端口不會進行交換功能,而是由路由處理器統一處理,而後根據 路由表查找並將數據包轉發到相應的輸出端口。
通常這種路由器不是單獨的路由器,而是工做站或者服務器充當的路由,這種路由器內部中,路由處理器其實就是
CPU
,而輸入端口其實只是網卡
。
輸入端口會根據轉發表定位輸出端口,而後再會進行分組轉發,那麼如今就有一個問題,是否是每個分組都有本身的一條鏈路呢?若是分組數量很是大,到達億級的話,也會有億個輸出端口路徑嗎?
咱們的潛意識中顯然不是的,來看下面一個例子。
下面是三個輸入端口對應了轉發表中的三個輸出鏈路的示例
能夠看到,對於這個例子來講,路由器轉發表中不須要那麼多條鏈路,只須要四條就夠,即對應輸出鏈路 0 1 2 3 。也就是說,可以使用 4 個轉發表就能夠實現億級鏈路。
如何實現呢?
使用這種風格的轉發表,路由器分組的地址 前綴(prefix)
會與該表中的表項進行匹配。
若是存在一個匹配項,那麼就會轉發到對應的鏈路上,可能很差理解,我舉個例子來講吧。
好比這時有一個分組是 11000011 10010101 00010000 0001100 到達,由於這個分組與 11000011 10010101 00010000 相匹配,因此路由器會轉發到 0 鏈路接口上。若是一個前綴不匹配上面三個輸出鏈路中的一種,那麼路由器將向鏈路接口 3 進行轉發。
路由匹配遵循 最長前綴原則(longest prefix matching rule)
,最長匹配原則故名思義就是若是有兩個匹配項一個長一個短的話,就匹配最長的。
一旦經過查找功能肯定了分組的輸出端口後,那麼該分組就會進入交換結構。在進入交換結構時,若是交換結構正在被使用,就會阻塞新到的分組,等到交換結構調度新的分組。
交換結構是路由器的核心功能,經過交換功能把分組從輸入端口轉發至輸出端口,這就是交換結構的主要功能。交換結構有多種形式,主要分爲 經過內存交換、經過總線交換、經過互聯網絡進行交換,下面咱們分開來探討一下。
內存交換
的,在輸入端口和輸出端口之間是經過 CPU 進行的。輸入端口和輸出端口的功能就好像傳統操做系統中的 I/O 設備同樣。當一個分組到達輸入端口時,這個端口會首先以中斷
的方式向路由選擇器發出信號,將分組從輸入端口拷貝到內存中。而後,路由選擇處理器從分組首部中提取目標地址,在轉發表中找出適當的輸出端口進行轉發,同時將分組複製到輸出端口的緩存中。這裏須要注意一點,若是內存帶寬以每秒讀取或者寫入 B 個數據包,那麼總的交換機吞吐量(數據包從輸入端口到輸出端口的總速率) 必須小於 B/2。
標籤
,而後分組經由總線發送給全部的輸出端口,每一個輸出端口都會判斷標籤中的端口和本身的是否匹配,若是匹配的話,那麼這個輸出端口就會把標籤拆掉,這個標籤只用於交換機內部跨越總線。若是同時有 多個
分組到達路由器的話,那麼只有一個分組可以被處理,其餘分組須要再進入交換結構前等待。每條垂直的的總線在交叉點與每條水平的總線交叉,交叉點經過交換結構控制器可以在任什麼時候候開啓和閉合。當分組到達輸入端口 A 時,若是須要轉發到端口 X,交換機控制器會閉合 A 到 X 交叉部分的交叉點,而後端口 A 在總線上進行分組轉發。這種網絡互聯式的交換結構是 非阻塞的(non-blocking)
的,也就是說 A -> X 的交叉點閉合不會影響 B -> Y 的鏈路。若是來自兩個不一樣輸入端口的兩個分組其目的地爲相同的輸出端口的話,這種狀況下只能有一個分組被交換,另一個分組必須進行等待。
以下圖所示,輸出端口處理取出已經存放在輸出端口內存中的分組並將其發送到輸出鏈路上。包括選擇和去除排隊的分組進行傳輸,執行所需的鏈路層和物理層的功能。
在輸入端口中有等待進入交換的排隊隊列,而在輸出端口中有等待轉發的排隊隊列,排隊的位置和程度取決於流量負載、交換結構的相對頻率和線路速率。
隨着隊列的不斷增長,會致使路由器的緩存空間被耗盡,進而使沒有內存能夠存儲溢出的隊列,導致分組出現丟包(packet loss)
,這就是咱們說的在網絡中丟包或者被路由器丟棄。
下面咱們經過輸入端口的排隊隊列和輸出端口的排隊隊列來介紹一下可能出現的排隊狀況。
若是交換結構的處理速度沒有輸入隊列到達的速度快,在這種狀況下,輸入端口將會出現排隊狀況,到達交換結構前的分組會加入輸入端口隊列中,以等待經過交換結構傳送到輸出端口。
爲了描述清楚輸入隊列,咱們假設如下狀況:
以下圖所示
在 A 隊列中,輸入隊列中的兩個分組會發送至同一個目的地 X,假設在交換結構正要發送 A 中的分組,在這個時候,C 隊列中也有一個分組發送至 X,在這種狀況下,C 中發送至 X 的分組將會等待,不只如此,C 隊列中發送至 Y 輸出端口的分組也會等待,即便 Y 中沒有出現競爭的狀況。這種現象叫作 線路前部阻塞(Head-Of-The-Line, HOL)
。
咱們下面討論輸出隊列中出現等待的狀況。假設交換速率要比輸入/輸出的傳輸速率快不少,並且有 N 個輸入分組的目的地是轉發至相同的輸出端口。在這種狀況下,在向輸出鏈路發送分組的過程當中,將會有 N 個新分組到達傳輸端口。由於輸出端口在一個單位時間內只能傳輸一個分組,那麼這 N 個分組將會等待。然而在等待 N 個分組被處理的過程當中,同時又有 N 個分組到達,因此 ,分組隊列可以在輸出端口造成。這種狀況下最終會由於分組數量變的足夠大,從而耗盡
輸出端口的可用內存。
若是沒有足夠的內存來緩存分組的話,就必須考慮其餘的方式,主要有兩種:一種是丟失分組,採用 棄尾(drop-tail)
的方法;一種是刪除一個或多個已經排隊的分組,從而來爲新的分組騰出空間。
網絡層的策略對 TCP 擁塞控制影響很大的就是路由器的分組丟棄策略。在最簡單的狀況下,路由器的隊列一般都是按照 FCFS 的規則處理到來的分組。因爲隊列長度老是有限的,所以當隊列已經滿了的時候,之後再到達的全部分組(若是可以繼續排隊,這些分組都將排在隊列的尾部)將都被丟棄。這就叫作尾部丟棄策略。
一般狀況下,在緩衝填滿以前將其丟棄是更好的策略。
如上圖所示,A B C 每一個輸入端口都到達了一個分組,並且這個分組都是發往 X 的,同一時間只能處理一個分組,而後這時,又有兩個分組分別由 A B 發往 X,因此此時有 4 個分組在 X 中進行等待。
等上一個分組被轉發完成後,輸出端口就會選擇在剩下的分組中根據 分組調度(packet scheduleer)
選擇一個分組來進行傳輸,咱們下面就會聊到分組傳輸。
如今咱們來討論一下分組調度次序的問題,即排隊的分組如何經輸出鏈路傳輸的問題。咱們生活中有無數排隊的例子,可是咱們生活中通常的排隊算法都是 先來先服務(FCFS)
,也是先進先出(FIFO)
。
先進先出就映射爲數據結構中的隊列
,只不過它如今是鏈路調度規則的排隊模型。
FIFO 調度規則按照分組到達輸出鏈路隊列的相同次序來選擇分組,先到達隊列的分組將先會被轉發。在這種抽象模型中,若是隊列已滿,那麼棄尾的分組將是隊列末尾的後面一個。
優先級排隊是先進先出排隊的改良版本,到達輸出鏈路的分組被分類放入輸出隊列中的優先權類,以下圖所示
一般狀況下,每一個優先級不一樣的分組有本身的優先級類,每一個優先級類有本身的隊列,分組傳輸會首先從優先級高的隊列中進行,在同一類優先級的分組之間的選擇一般是以 FIFO 的方式完成。
在循環加權公平規則(round robin queuing discipline)
下,分組像使用優先級那樣被分類。然而,在類之間卻不存在嚴格的服務優先權。循環調度器在這些類之間循環輪流提供服務。以下圖所示
在循環加權公平排隊中,類 1 的分組被傳輸,接着是類 2 的分組,最後是類 3 的分組,這算是一個循環,而後接下來又從新開始,又從 1 -> 2 -> 3 這個順序進行輪詢。每一個隊列也是一個先入先出的隊列。
這是一種所謂的保持工做排隊(work-conserving queuing)
的規則,就是說若是輪詢的過程當中發現有空隊列,輸出端口不會等待分組,而是繼續輪詢下面的隊列。
路由器對分組進行轉發後,就會把數據包傳到網絡上,數據包最終是要傳遞到客戶端或者服務器上的,那麼數據包怎麼知道要發往哪裏呢?起到關鍵做用的就是 IP 協議。
IP 主要分爲三個部分,分別是 IP 尋址、路由和分包組包。下面咱們主要圍繞這三點進行闡述。
既然一個數據包要在網絡上傳輸,那麼確定須要知道這個數據包到底發往哪裏,也就是說須要一個目標地址信息,IP 地址就是鏈接網絡中的全部主機進行通訊的目標地址,所以,在網絡上的每一個主機都須要有本身的 IP 地址。
在 IP 數據報發送的鏈路中,有可能鏈路很是長,好比說由中國發往美國的一個數據報,因爲網絡抖動等一些意外因素可能會致使數據報丟失,這時咱們在這條鏈路中會放入一些 中轉站
,一方面可以確保數據報是否丟失,另外一方面可以控制數據報的轉發,這個中轉站就是咱們前面聊過的路由器,這個轉發過程就是 路由控制
。
路由控制(Routing)
是指將分組數據發送到最終目標地址的功能,即便網絡複雜多變,也可以經過路由控制到達目標地址。所以,一個數據報可否到達目標主機,關鍵就在於路由器的控制。
這裏有一個名詞,就是 跳
,由於在一條鏈路中可能會佈滿不少路由器,路由器和路由器之間的數據報傳送就是跳,好比你和隔壁老王通訊,中間就可能會通過路由器 A-> 路由器 B -> 路由器 C 。
那麼一跳的範圍有多大呢?
一跳是指從源 MAC 地址到目標 MAC 地址之間傳輸幀的區間,這裏引出一個新的名詞,MAC 地址是啥?
MAC 地址指的就是計算機的物理地址(Physical Address)
,它是用來確認網絡設備位置的地址。在 OSI 網絡模型中,網絡層負責 IP 地址的定位,而數據鏈路層負責 MAC 地址的定位。MAC 地址用於在網絡中惟一標示一個網卡,一臺設備如有一或多個網卡,則每一個網卡都須要並會有一個惟一的 MAC 地址,也就是說 MAC 地址和網卡是緊密聯繫在一塊兒的。
路由器的每一跳都須要詢問當前中轉的路由器,下一跳應該跳到哪裏,從而跳轉到目標地址。而不是數據報剛開始發送後,網絡中全部的通路都會顯示出來,這種屢次跳轉也叫作多跳路由
。
現現在有兩個版本的 IP 地址,IPv4 和 IPv6,咱們首先探討一下現現在還在普遍使用的 IPv4 地址,後面再考慮 IPv6 。
IPv4 由 32 位正整數來表示,在計算機內部會轉化爲二進制來處理,可是二進制不符合人類閱讀的習慣,因此咱們根據易讀性
的原則把 32 位的 IP 地址以 8 位爲一組,分紅四組,每組之間以 .
進行分割,再將每組轉換爲十進制數。以下圖所示
那麼上面這個 32 位的 IP 地址就會被轉換爲十進制的 156.197.1.1。
除此以外,從圖中咱們還能夠獲得以下信息
每一個這樣 8 位位一組的數字,天然是非負數,其取值範圍是 [0,255]。
IP 地址的總個數有 2^32 次冪個,這個數值算下來是 4294967296
,大概能容許 43 億臺設備鏈接到網絡。實際上真的如此嗎?
實際上 IP 不會以主機的個數來配置的,而是根據設備上的 網卡(NIC)
進行配置,每一塊網卡都會設置一個或者多個 IP 地址,並且一般一臺路由器會有至少兩塊網卡,因此能夠設置兩個以上的 IP 地址,因此主機的數量遠遠達不到 43 億。
IP 地址由 網絡標識
和 主機標識
兩部分組成,網絡標識表明着網絡地址,主機標識表明着主機地址。網絡標識在數據鏈路的每一個段配置不一樣的值。網絡標識必須保證相互鏈接的每一個段的地址都不重複。而相同段內相連的主機必須有相同的網絡地址。IP 地址的 主機標識
則不容許在同一網段內重複出現。
舉個例子來講:好比說我在石家莊(好像不用好比昂),我所在的小區的某一棟樓就至關因而網絡標識,某一棟樓的第幾戶就至關因而個人主機標識,固然若是你有整棟樓的話,那就當我沒說。你能夠經過xx省xx市xx區xx路xx小區xx棟來定位個人網絡標識,這一棟的第幾戶就至關因而個人網絡標識。
IP 地址分爲四類,分別是 A類、B類、C類、D類、E類,它會根據 IP 地址中的第 1 位到第 4 位的比特對網絡標識和主機標識進行分類。
A 類
:(1.0.0.0 - 126.0.0.0)(默認子網掩碼:255.0.0.0 或 0xFF000000)第一個字節爲網絡號,後三個字節爲主機號。該類 IP 地址的最前面爲 0 ,因此地址的網絡號取值於 1~126 之間。通常用於大型網絡。
B 類
:(128.0.0.0 - 191.255.0.0)(默認子網掩碼:255.255.0.0 或 0xFFFF0000)前兩個字節爲網絡號,後兩個字節爲主機號。該類 IP 地址的最前面爲 10 ,因此地址的網絡號取值於 128~191 之間。通常用於中等規模網絡。
C 類
:(192.0.0.0 - 223.255.255.0)(子網掩碼:255.255.255.0 或 0xFFFFFF00)前三個字節爲網絡號,最後一個字節爲主機號。該類 IP 地址的最前面爲 110 ,因此地址的網絡號取值於 192~223 之間。通常用於小型網絡。
D 類
:是多播地址。該類 IP 地址的最前面爲 1110 ,因此地址的網絡號取值於 224~239 之間。通常用於多路廣播用戶。
E 類
:是保留地址。該類 IP 地址的最前面爲 1111 ,因此地址的網絡號取值於 240~255 之間。
爲了方便理解,我畫了一張 IP 地址分類圖,以下所示
根據不一樣的 IP 範圍,有下面不一樣的地總空間分類
子網掩碼(subnet mask)
又叫作網絡掩碼,它是一種用來指明一個 IP 地址的哪些位標識的是主機所在的網絡。子網掩碼是一個 32位 地址,用於屏蔽 IP 地址的一部分以區別網絡標識和主機標識。
一個 IP 地址只要肯定了其分類,也就肯定了它的網絡標識和主機標識,由此,各個分類所表示的網絡標識範圍以下
用 1
表示 IP 網絡地址的比特範圍,0
表示 IP 主機地址的範圍。將他們用十進制表示,那麼這三類的表示以下
在IPv4 的幾類地址中,有幾個保留的地址空間不能在互聯網上使用。這些地址用於特殊目的,不能在局域網外部路由。
目前,全球 Internet 中共存有兩個IP版本:IP 版本 4(IPv4)
和 IP 版本6(IPv6)
。 IP 地址由二進制值組成,可驅動 Internet 上全部數據的路由。 IPv4 地址的長度爲 32 位,而 IPv6 地址的長度爲 128 位。
Internet IP 資源由 Internet 分配號碼機構(IANA)
分配給區域 Internet 註冊表(RIR),例如 APNIC,該機構負責根 DNS ,IP 尋址和其餘 Internet 協議資源。
下面咱們就一塊兒認識一下 IP 協議中很是重要的兩個版本 IPv4 和 IPv6。
IPv4 的全稱是 Internet Protocol version 4
,是 Internet 協議的第四版。IPv4 是一種無鏈接的協議,這個協議會盡最大努力交付數據包,也就是說它不能保證任何數據包能到達目的地,也不能保證全部的數據包都會按照正確的順序到達目標主機,這些都是由上層好比傳輸控制協議控制的。也就是說,單從 IP 看來,這是一個不可靠的協議。
前面咱們講過網絡層分組被稱爲
數據報
,因此咱們接下來的敘述也會圍繞着數據報展開。
IPv4 的數據報格式以下
IPv4 數據報中的關鍵字及其解釋
版本字段(Version)
佔用 4 bit,通訊雙方使用的版本必須一致,對於 IPv4 版原本說,字段值是 4。首部長度(Internet Header Length)
佔用 4 bit,首部長度說明首部有多少 32 位(4 字節)。因爲 IPv4 首部可能包含不肯定的選項,所以這個字段被用來肯定數據的偏移量。大多數 IP 不包含這個選項,因此通常首部長度設置爲 5, 數據報爲 20 字節 。服務類型(Differential Services Codepoint,DSCP)
佔用 6 bit,以便使用不一樣的 IP 數據報,好比一些低時延、高吞吐量和可靠性的數據報。服務類型以下表所示擁塞通告(Explicit Congestion Notification,ECN)
佔用 2 bit,它容許在不丟棄報文的同時通知對方網絡擁塞的發生。ECN 是一種可選的功能,僅當兩端都支持並但願使用,且底層網絡支持時才被使用。 最開始 DSCP 和 ECN 統稱爲 TOS,也就是區分服務,可是後來被細化爲了 DSCP 和 ECN。
數據報長度(Total Length)
佔用 16 bit,這 16 位是包括在數據在內的總長度,理論上數據報的總長度爲 2 的 16 次冪 - 1,最大長度是 65535 字節,可是實際上數據報不多有超過 1500 字節的。IP 規定全部主機都必須支持最小 576 字節的報文,但大多數現代主機支持更大的報文。當下層的數據鏈路協議的最大傳輸單元(MTU)
字段的值小於 IP 報文長度時,報文就必須被分片。
標識符(Identification)
佔用 16 bit,這個字段用來標識全部的分片,由於分片不必定會按序到達,因此到達目標主機的全部分片會進行重組,每產生一個數據報,計數器加1,並賦值給此字段。
標誌(Flags)
佔用 3 bit,標誌用於控制和識別分片,這 3 位分別是
禁止分片(Don’t Fragment,DF)
,當 DF = 0 時才容許分片;更多分片(More Fragment,MF)
,MF = 1 表明後面還有分片,MF = 0 表明已是最後一個分片。若是 DF 標誌被設置爲 1 ,可是路由要求必須進行分片,那麼這條數據報回丟棄
分片偏移(Fragment Offset)
佔用 13 位,它指明瞭每一個分片相對於原始報文開頭的偏移量,以 8 字節做單位。
存活時間(Time To Live,TTL)
佔用 8 位,存活時間避免報文在互聯網中迷失
,好比陷入路由環路。存活時間以秒爲單位,但小於一秒的時間均向上取整到一秒。在現實中,這實際上成了一個跳數計數器:報文通過的每一個路由器都將此字段減 1,當此字段等於 0 時,報文再也不向下一跳傳送並被丟棄,這個字段最大值是 255。
協議(Protocol)
佔用 8 位,這個字段定義了報文數據區使用的協議。協議內容能夠在 https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml 官網上獲取。
首部校驗和(Header Checksum)
佔用 16 位,首部校驗和會對字段進行糾錯檢查,在每一跳中,路由器都要從新計算出的首部檢驗和並與此字段進行比對,若是不一致,此報文將會被丟棄。
源地址(Source address)
佔用 32 位,它是 IPv4 地址的構成條件,源地址指的是數據報的發送方
目的地址(Destination address)
佔用 32 位,它是 IPv4 地址的構成條件,目標地址指的是數據報的接收方
選項(Options)
是附加字段,選項字段佔用 1 - 40 個字節不等,通常會跟在目的地址以後。若是首部長度 > 5,就應該考慮選項字段。
數據
不是首部的一部分,所以並不被包含在首部檢驗和中。
在 IP 發送的過程當中,每一個數據報的大小是不一樣的,每一個鏈路層協議能承載的網絡層分組也不同,有的協議可以承載大數據報,有的卻只能承載很小的數據報,不一樣的鏈路層可以承載的數據報大小以下。
一個鏈路層幀能承載的最大數據量叫作最大傳輸單元(Maximum Transmission Unit, MTU)
,每一個 IP 數據報封裝在鏈路層幀中從一臺路由器傳到下一臺路由器。由於每一個鏈路層所支持的最大 MTU 不同,當數據報的大小超過 MTU 後,會在鏈路層進行分片,每一個數據報會在鏈路層單獨封裝,每一個較小的片都被稱爲 片(fragement)
。
每一個片在到達目的地後會進行重組,準確的來講是在運輸層以前會進行重組,TCP 和 UDP 都會但願發送完整的、未分片的報文,出於性能的緣由,分片重組不會在路由器中進行,而是會在目標主機中進行重組。
當目標主機收到從發送端發送過來的數據報後,它須要肯定這些數據報中的分片是不是由源數據報分片傳遞過來的,若是是的話,還須要肯定什麼時候收到了分片中的最後一片
,而且這些片會如何拼接一塊兒成爲數據報。
針對這些潛在的問題,IPv4 設計者將 標識、標誌和片偏移放在 IP 數據報首部中。當生成一個數據報時,發送主機會爲該數據報設置源和目的地址的同時貼上標識號
。發送主機一般將它發送的每一個數據報的標識 + 1。當某路由器須要對一個數據報分片時,造成的每一個數據報具備初始數據報的源地址、目標地址和標識號。當目的地從同一發送主機收到一系列數據報時,它可以檢查數據報的標識號以肯定哪些數據是由源數據報發送過來的。因爲 IP 是一種不可靠的服務,分片可能會在網路中丟失,鑑於這種狀況,一般會把分片的最後一個比特設置爲 0 ,其餘分片設置爲 1,同時使用偏移字段指定分片應該在數據報的哪一個位置。
IPv4 支持三種不一樣類型的尋址模式,分別是
隨着端系統接入的愈來愈多,IPv4 已經沒法知足分配了,因此,IPv6 應運而生,IPv6 就是爲了解決 IPv4 的地址耗盡問題而被標準化的網際協議。IPv4 的地址長度爲 4 個 8 字節,即 32 比特, 而 IPv6 的地址長度是原來的四倍,也就是 128 比特,通常寫成 8 個 16 位字節。
從 IPv4 切換到 IPv6 及其耗時,須要將網絡中全部的主機和路由器的 IP 地址進行設置,在互聯網不斷普及的今天,替換全部的 IP 是一個工做量及其龐大的任務。咱們後面會說。
咱們先來看一下 IPv6 的地址是怎樣的
版本
與 IPv4 同樣,版本號由 4 bit 構成,IPv6 版本號的值爲 6。流量類型(Traffic Class)
佔用 8 bit,它就至關於 IPv4 中的服務類型(Type Of Service)。流標籤(Flow Label)
佔用 20 bit,這 20 比特用於標識一條數據報的流,可以對一條流中的某些數據報給出優先權,或者它可以用來對來自某些應用的數據報給出更高的優先權,只有流標籤、源地址和目標地址一致時,纔會被認爲是一個流。有效載荷長度(Payload Length)
佔用 16 bit,這 16 比特值做爲一個無符號整數,它給出了在 IPv6 數據報中跟在鼎昌 40 字節數據報首部後面的字節數量。下一個首部(Next Header)
佔用 8 bit,它用於標識數據報中的內容須要交付給哪一個協議,是 TCP 協議仍是 UDP 協議。跳限制(Hop Limit)
佔用 8 bit,這個字段與 IPv4 的 TTL 意思相同。數據每通過一次路由就會減 1,減到 0 則會丟棄數據。源地址(Source Address)
佔用 128 bit (8 個 16 位 ),表示發送端的 IP 地址。目標地址(Destination Address)
佔用 128 bit (8 個 16 位 ),表示接收端 IP 地址。能夠看到,相較於 IPv4 ,IPv6 取消了下面幾個字段
IPv6 首部長度固定,沒法將選項字段加入其中,取而代之的是 IPv6 使用了擴展首部
擴展首部一般介於 IPv6 首部與 TCP/UDP 首部之間,在 IPv4 中可選長度固定爲 40 字節,在 IPv6 中沒有這樣的限制。IPv6 的擴展首部能夠是任意長度。擴展首部中還能夠包含擴展首部協議和下一個擴展字段。
IPv6 首部中沒有標識和標誌字段,對 IP 進行分片時,須要使用到擴展首部。
具體的擴展首部表以下所示
下面咱們來看一下 IPv6 都有哪些特色
IPv6 的特色在 IPv4 中得以實現,可是即使實現了 IPv4 的操做系統,也未必實現了 IPv4 的全部功能。而 IPv6 卻將這些功能大衆化了,也就代表這些功能在 IPv6 已經進行了實現,這些功能主要有
地址空間變得更大:這是 IPv6 最主要的一個特色,即支持更大的地址空間。
精簡報文結構: IPv6 要比 IPv4 精簡不少,IPv4 的報文長度不固定,並且有一個不斷變化的選項字段;IPv6 報文段固定,而且將選項字段,分片的字段移到了 IPv6 擴展頭中,這就極大的精簡了 IPv6 的報文結構。
實現了自動配置:IPv6 支持其主機設備的狀態和無狀態自動配置模式。這樣,沒有 DHCP 服務器
不會中止跨段通訊。
層次化的網絡結構: IPv6 再也不像 IPv4 同樣按照 A、B、C等分類來劃分地址,而是經過 IANA -> RIR -> ISP 這樣的順序來分配的。IANA 是國際互聯網號碼分配機構,RIR 是區域互聯網註冊管理機構,ISP 是一些運營商(例如電信、移動、聯通)。
IPSec:IPv6 的擴展報頭中有一個認證報頭、封裝安全淨載報頭,這兩個報頭是 IPsec 定義的。經過這兩個報頭網絡層本身就能夠實現端到端的安全,而無需像 IPv4 協議同樣須要其餘協議的幫助。
支持任播:IPv6 引入了一種新的尋址方式,稱爲任播尋址。
咱們知道,IPv6 地址長度爲 128 位,他所能表示的範圍是 2 ^ 128 次冪,這個數字很是龐大,幾乎涵蓋了你能想到的全部主機和路由器,那麼 IPv6 該如何表示呢?
通常咱們將 128 比特的 IP 地址以每 16 比特爲一組,並用 :
號進行分隔,若是出現連續的 0 時還能夠將 0 省略,並用 ::
兩個冒號隔開,記住,一個 IP 地址只容許出現一次兩個連續的冒號。
下面是一些 IPv6 地址的示例
如上圖所示,A120 和 4CD 中間的 0 被 :: 所取代了。
咱們上面聊了聊 IPv4 和 IPv6 的報文格式、報文含義是什麼、以及 IPv4 和 IPv6 的特徵分別是什麼,看完上面的內容,你已經知道了 IPv4 如今立刻就變的不夠用了,並且隨着 IPv6 的不斷髮展和引用,雖然新型的 IPv6 能夠作到向後兼容
,即 IPv6 能夠收發 IPv4 的數據報,可是已經部署的具備 IPv4 能力的系統卻不可以處理 IPv6 數據報。因此 IPv4 噬需遷移到 IPv6,遷移並不意味着將 IPv4 替換爲 IPv6。這僅意味着同時啓用 IPv6 和 IPv4。
那麼如今就有一個問題了,IPv4 如何遷移到 IPv6 呢?這就是咱們接下來討論的重點。
最簡單的方式就是設置一個標誌日,指定某個時間點和日期,此時全球的因特網機器都會在這時關機從 IPv4 遷移到 IPv6 。上一次重大的技術遷移是在 35 年前,可是很顯然,不用我過多解釋,這種狀況確定是 不行的
。影響不可估量不說,如何保證全球人類都能知道如何設置本身的 IPv6 地址?一個設計數十億臺機器的標誌日如今是想都不敢想的。
如今已經在實踐中使用的從 IPv4 遷移到 IPv6 的方法是 隧道技術(tunneling)
。
什麼是隧道技術呢?
隧道技術是一種使用互聯網絡的基礎設施在網絡之間的傳輸數據的方式,使用隧道傳遞的數據能夠是不一樣協議的數據幀或包。使用隧道技術所聽從的協議叫作隧道協議(tunneling protocol)
。隧道協議會將這些協議的數據幀或包封裝在新的包頭中發送。新的包頭提供了路由信息,從而使封裝的負載數據可以經過互聯網絡進行傳遞。
使用隧道技術通常都會建一個隧道
,建隧道的依據以下:
好比兩個 IPv6 節點(下方 B、E)要使用 IPv6 數據報進行交互,可是它們是經由兩個 IPv4 的路由器進行互聯的。那麼咱們就須要將 IPv6 節點和 IPv4 路由器組成一個隧道,以下圖所示
藉助於隧道,在隧道發送端的 IPv6 節點可將整個 IPv6 數據報放到一個 IPv4 數據報的數據(有效載荷)
字段中,因而,IPv4 數據報的地址被設置爲指向隧道接收端的 IPv6 的節點,好比上面的 E 節點。而後再發送給隧道中的第一個節點 C,以下所示
隧道中間的 IPv4 提供路由,路由器不知道這個 IPv4 內部包含一個指向 IPv6 的地址。隧道接收端的 IPv6 節點收到 IPv4 數據報,會肯定這個 IPv4 數據報含有一個 IPv6 數據報,經過觀察數據報長度和數據得知。而後取出 IPv6 數據報,再爲 IPv6 提供路由,就好像兩個節點直接相連傳輸數據報同樣。
這篇文章是計算機網絡系列的連載文章,這篇咱們主要探討了網絡層的相關知識、路由器的內部構造、路由器如何實現轉發的,IP 協議相關內容:包括 IP 地址、IPv4 和 IPv6 的相關內容,最後咱們探討了如何使 IPv4 遷移到 IPv6 。
**另外,添加個人微信 becomecxuan,加入每日一題羣,天天一道面試題分享,更多內容請參見個人 Github,成爲最好的 bestJavaer
我本身肝了六本 PDF,微信搜索「程序員cxuan」關注公衆號後,在後臺回覆 cxuan ,領取所有 PDF,這些 PDF 以下