主頁 > 後端開發 > IP 基礎知識“全家桶”,45 張圖一套帶走

IP 基礎知識“全家桶”,45 張圖一套帶走

2021-01-16 06:45:14 後端開發


前言

前段時間,有讀者希望我寫一篇關于 IP 分類地址、子網劃分等的文章,他反饋常常混淆,摸不著頭腦,

那么,說來就來!而且要盤就盤全一點,順便挑戰下小林的圖解功力,所以就來個 IP 基礎知識全家桶

吃完這個 IP 基礎知識全家桶全家桶,包你撐著肚子喊出:“真香!

不多說,直接上菜,共分為三道菜

  • 首先是前菜 「 IP 基本認識 」
  • 其次是主菜 「IP 地址的基礎知識」
  • 最后是點心 「IP 協議相關技術」
  • img

正文

前菜 —— IP 基本認識

IP 在 TCP/IP 參考模型中處于第三層,也就是網路層

網路層的主要作用是:實作主機與主機之間的通信,也叫點對點(end to end)通信,

img

網路層與資料鏈路層有什么關系呢?

有的小伙伴分不清 IP(網路層) 和 MAC (資料鏈路層)之間的區別和關系,

其實很容易區分,在上面我們知道 IP 的作用是主機之間通信中的,而 MAC 的作用則是實作「直連」的兩個設備之間通信,而 IP 則負責在「沒有直連」的兩個網路之間進行通信傳輸,

舉個生活的栗子,小林要去一個很遠的地方旅行,制定了一個行程表,其間需先后乘坐飛機、地鐵、公交車才能抵達目的地,為此小林需要買飛機票,地鐵票等,

飛機票和地鐵票都是去往特定的地點的,每張票只能夠在某一限定區間內移動,此處的「區間內」就如同通信網路中資料鏈路,

在區間內移動相當于資料鏈路層,充當區間內兩個節點傳輸的功能,區間內的出發點好比源 MAC 地址,目標地點好比目的 MAC 地址,

整個旅游行程表就相當于網路層,充當遠程定位的功能,行程的開始好比源 IP,行程的終點好比目的 IP 地址,

img

如果小林只有行程表而沒有車票,就無法搭乘交通工具到達目的地,相反,如果除了車票而沒有行程表,恐怕也很難到達目的地,因為小林不知道該坐什么車,也不知道該在哪里換乘,

因此,只有兩者兼備,既有某個區間的車票又有整個旅行的行程表,才能保證到達目的地,與此類似,計算機網路中也需要「資料鏈路層」和「網路層」這個分層才能實作向最終目標地址的通信,

還有重要一點,旅行途中我們雖然不斷變化了交通工具,但是旅行行程的起始地址和目的地址始終都沒變,其實,在網路中資料包傳輸中也是如此,*源IP地址和目標IP地址在傳輸程序中是不會變化的,只有源 MAC 地址和目標 MAC 一直在變化*

主菜 —— IP 地址的基礎知識

在 TCP/IP 網路通信時,為了保證能正常通信,每個設備都需要配置正確的 IP 地址,否則無法實作正常的通信,

IP 地址(IPv4 地址)由 32 位正整數來表示,IP 地址在計算機是以二進制的方式處理的,

而人類為了方便記憶采用了點分十進制的標記方式,也就是將 32 位 IP 地址以每 8 位為組,共分為 4 組,每組以「.」隔開,再將每組轉換成十進制,

img

那么,IP 地址最大值也就是

img

也就說,最大允許 43 億臺計算機連接到網路,

實際上,IP 地址并不是根據主機臺數來配置的,而是以網卡,像服務器、路由器等設備都是有 2 個以上的網卡,也就是它們會有 2 個以上的 IP 地址,

img

因此,讓 43 億臺計算機全部連網其實是不可能的,更何況 IP 地址是由「網路標識」和「主機標識」這兩個部分組成的,所以實際能夠連接到網路的計算機個數更是少了很多,

可能有的小伙伴提出了疑問,現在不僅電腦配了 IP, 手機、IPad 等電子設備都配了 IP 呀,照理來說肯定會超過 43 億啦,那是怎么能夠支持這么多 IP 的呢?

因為會根據一種可以更換 IP 地址的技術 NAT,使得可連接計算機數超過 43 億臺,NAT 技術后續會進一步討論和說明,

IP 地址的分類

互聯網誕生之初,IP 地址顯得很充裕,于是計算機科學家們設計了分類地址

IP 地址分類成了 5 種型別,分別是 A 類、B 類、C 類、D 類、E 類,

img

上圖中黃色部是分類號,用以區分 IP 地址類別,

什么是 A、B、C 類地址?

其中對于 A、B、C 類主要分為兩個部分,分別是網路號和主機號,這很好理解,好比小林是 A 小區 1 棟 101 號,你是 B 小區 1 棟 101 號,

我們可以用下面這個表格, 就能很清楚的知道 A、B、C 分類對應的地址范圍、最大主機個數,

img

A、B、C 分類地址最大主機個數是如何計算的呢?

最大主機個數,就是要看主機號的位數,如 C 類地址的主機號占 8 位,那么 C 類地址的最大主機個數

img

為什么要減 2 呢?

因為在 IP 地址中,有兩個 IP 是特殊的,分別是主機號全為 1 和 全為 0 地址,

img

  • 主機號全為 1 指定某個網路下的所有主機,用于廣播
  • 主機號全為 0 指定某個網路

因此,在分配程序中,應該去掉這兩種情況,

廣播地址用于什么?

廣播地址用于在同一個鏈路中相互連接的主機之間發送資料包

學校班級中就有廣播的例子,在準備上課的時候,通常班長會喊:“上課, 全體起立!”,班里的同學聽到這句話是不是全部都站起來了?這個句話就有廣播的含義,

當主機號全為 1 時,就表示該網路的廣播地址,例如把 172.20.0.0/16 用二進制表示如下:

10101100.00010100.00000000.00000000

將這個地址的主機部分全部改為 1,則形成廣播地址:

10101100.00010100.11111111.11111111

再將這個地址用十進制表示,則為 172.20.255.255

廣播地址可以分為本地廣播和直接廣播兩種,

  • 在本網路內廣播的叫做本地廣播,例如網路地址為 192.168.0.0/24 的情況下,廣播地址是 192.168.0.255 ,因為這個廣播地址的 IP 包會被路由器屏蔽,所以不會到達 192.168.0.0/24 以外的其他鏈路上,
  • 在不同網路之間的廣播叫做直接廣播,例如網路地址為 192.168.0.0/24 的主機向 192.168.1.255/24 的目標地址發送 IP 包,收到這個包的路由器,將資料轉發給192.168.1.0/24,從而使得所有 192.168.1.1~192.168.1.254 的主機都能收到這個包(由于直接廣播有一定的安全問題,多數情況下會在路由器上設定為不轉發),

img

什么是 D、E 類地址?

而 D 類和 E 類地址是沒有主機號的,所以不可用于主機 IP,D 類常被用于多播,E 類是預留的分類,暫時未使用,

img

多播地址用于什么?

多播用于*將包發送給特定組內的所有主機*

還是舉班級的栗子,老師說:“最后一排的同學,上來做這道數學題,”,老師是指定的是最后一排的同學,也就是多播的含義了,

由于廣播無法穿透路由,若想給其他網段發送同樣的包,就可以使用可以穿透路由的多播(組播),

img

多播使用的 D 類地址,其前四位是 1110 就表示是多播地址,而剩下的 28 位是多播的組編號,

從 224.0.0.0 ~ 239.255.255.255 都是多播的可用范圍,其劃分為以下三類:

  • 224.0.0.0 ~ 224.0.0.255 為預留的組播地址,只能局域網中,路由器是不會進行轉發的
  • 224.0.1.0 ~ 238.255.255.255 為用戶可用的組播地址,可以用于 Internet 上
  • 239.0.0.0 ~ 239.255.255.255 為本地管理組播地址,可供內部網在內部使用,僅在特定的本地范圍內有效

IP 分類的優點

不管是路由器還是主機決議到一個 IP 地址時候,我們判斷其 IP 地址的首位是否為 0,為 0 則為 A 類地址,那么就能很快的找出網路地址和主機地址,

其余分類判斷方式參考如下圖:

img

所以,這種分類地址的優點就是簡單明了、選路(基于網路地址)簡單

IP 分類的缺點

缺點一

同一網路下沒有地址層次,比如一個公司里用了 B 類地址,但是可能需要根據生產環境、測驗環境、開發環境來劃分地址層次,而這種 IP 分類是沒有地址層次劃分的功能,所以這就缺少地址的靈活性

缺點二

A、B、C類有個尷尬處境,就是不能很好的與現實網路匹配

  • C 類地址能包含的最大主機數量實在太少了,只有 254 個,估計一個網吧都不夠用,
  • 而 B 類地址能包含的最大主機數量又太多了,6 萬多臺機器放在一個網路下面,一般的企業基本達不到這個規模,閑著的地址就是浪費,

這兩個缺點,都可以在 CIDR 無分類地址解決,

無分類地址 CIDR

正因為 IP 分類存在許多缺點,所有后面提出了無分類地址的方案,即 CIDR

這種方式不再有分類地址的概念,32 位元的 IP 地址被劃分為兩部分,前面是網路號,后面是主機號

怎么劃分網路號和主機號的呢?

表示形式 a.b.c.d/x,其中 /x 表示前 x 位屬于網路號, x 的范圍是 0 ~ 32,這就使得 IP 地址更加具有靈活性,

比如 10.100.122.2/24,這種地址表示形式就是 CIDR,/24 表示前 24 位是網路號,剩余的 8 位是主機號,

img

還有另一種劃分網路號與主機號形式,那就是子網掩碼,掩碼的意思就是掩蓋掉主機號,剩余的就是網路號,

將子網掩碼和 IP 地址按位計算 AND,就可得到網路號,

img

為什么要分離網路號和主機號?

因為兩臺計算機要通訊,首先要判斷是否處于同一個廣播域內,即網路地址是否相同,如果網路地址相同,表明接受方在本網路上,那么可以把資料包直接發送到目標主機,

路由器尋址作業中,也就是通過這樣的方式來找到對應的網路號的,進而把資料包轉發給對應的網路內,

img

怎么進行子網劃分?

在上面我們知道可以通過子網掩碼劃分出網路號和主機號,那實際上子網掩碼還有一個作用,那就是劃分子網

子網劃分實際上是將主機地址分為兩個部分:子網網路地址和子網主機地址,形式如下:

img

  • 未做子網劃分的 ip 地址:網路地址+主機地址
  • 做子網劃分后的 ip 地址:網路地址+(子網網路地址+子網主機地址)

假設對 C 類地址進行子網劃分,網路地址 192.168.1.0,使用子網掩碼 255.255.255.192 對其進行子網劃分,

C 類地址中前 24 位 是網路號,最后 8 位是主機號,根據子網掩碼可知從 8 位主機號中借用 2 位作為子網號

img

由于子網網路地址被劃分成 2 位,那么子網地址就有 4 個,分別是 00、01、10、11,具體劃分如下圖:

img

劃分后的 4 個子網如下表格:

img

公有 IP 地址與私有 IP 地址

在 A、B、C 分類地址,實際上有分公有 IP 地址和 私有 IP 地址,

img

平時我們辦公室、家里、學校用的 IP 地址,一般都是私有 IP 地址,因為這些地址允許組織內部的 IT 人員自己管理、自己分配,而且可以重復,因此,你學校的某個私有 IP 地址和我學校的可以是一樣的,

就像每個小區都有自己的樓編號和門牌號,你小區家可以叫 1 棟 101 號,我小區家也可以叫 1 棟 101,沒有任何問題,但一旦出了小區,就需要帶上中山路 666 號(公網 IP 地址),是國家統一分配的,不能兩個小區都叫中山路 666,

所以,公有 IP 地址是有個組織統一分配的,假設你要開一個博客網站,那么你就需要去申請購買一個公有 IP,這樣全世界的人才能訪問,并且公有 IP 地址基本上要在整個互聯網范圍內保持唯一,

img

公有 IP 地址由誰管理呢?

私有 IP 地址通常是內部的 IT 人員值管理,公有 IP 地址是由 ICANN 組織管理,中文叫「互聯網名稱與數字地址分配機構」,

IANA 是 ICANN 的其中一個機構,它負責分配互聯網 IP 地址,是按州的方式層層分配,

img

  • ARIN 北美地區
  • LACNIC 拉丁美洲和一些加勒比群島
  • RIPE NCC 歐洲、中東和中亞
  • AfriNIC 非洲地區
  • APNIC 亞太地區

其中,在中國是由 CNNIC 的機構進行管理,它是中國國內唯一指定的全域 IP 地址管理的組織,

IP 地址與路由控制

IP地址的網路地址這一部分是用于進行路由控制,

路由控制表中記錄著網路地址與下一步應該發送至路由器的地址,在主機和路由器上都會有各自的路由器控制表,

在發送 IP 包時,首先要確定 IP 包首部中的目標地址,再從路由控制表中找到與該地址具有相同網路地址的記錄,根據該記錄將 IP 包轉發給相應的下一個路由器,如果路由控制表中存在多條相同網路地址的記錄,就選擇相同位數最多的網路地址,也就是最長匹配,

下面以下圖的網路鏈路作為例子說明:

img

  1. 主機 A 要發送一個 IP 包,其源地址是 10.1.1.30 和目標地址是 10.1.2.10,由于沒有在主機 A 的路由表找到與目標地址 10.1.2.10 的網路地址,于是把包被轉發到默認路由(路由器 1
  2. 路由器 1 收到 IP 包后,也在路由器 1 的路由表匹配與目標地址相同的網路地址記錄,發現匹配到了,于是就把 IP 資料包轉發到了 10.1.0.2 這臺路由器 2
  3. 路由器 2 收到后,同樣對比自身的路由表,發現匹配到了,于是把 IP 包從路由器 210.1.2.1 這個介面出去,最終經過交換機把 IP 資料包轉發到了目標主機

環回地址是不會流向網路

環回地址是在同一臺計算機上的程式之間進行網路通信時所使用的一個默認地址,

計算機使用一個特殊的 IP 地址 *127.0.0.1 作為環回地址*與該地址具有相同意義的是一個叫做 localhost 的主機名,

使用這個 IP 或主機名時,資料包不會流向網路,

IP 分片與重組

每種資料鏈路的最大傳輸單元 MTU 都是不相同的,如 FDDI 資料鏈路 MTU 4352、以太網的 MTU 是 1500 位元組等,

每種資料鏈路的 MTU 之所以不同,是因為每個不同型別的資料鏈路的使用目的不同,使用目的不同,可承載的 MTU 也就不同,

其中,我們最常見資料鏈路是以太網,它的 MTU 是 1500 位元組,

那么當 IP 資料包大小大于 MTU 時, IP 資料包就會被分片,

經過分片之后的 IP 資料報在被重組的時候,只能由目標主機進行,路由器是不會進行重組的,

假設發送方發送一個 4000 位元組的大資料報,若要傳輸在以太網鏈路,則需要把資料報分片成 3 個小資料報進行傳輸,再交由接收方重組成大資料報,

img

在分片傳輸中,一旦某個分片丟失,則會造成整個 IP 資料報作廢,所以 TCP 引入了 MSS 也就是在 TCP 層進行分片不由 IP 層分片,那么對于 UDP 我們盡量不要發送一個大于 MTU 的資料報文,

IPv6 基本認識

IPv4 的地址是 32 位的,大約可以提供 42 億個地址,但是早在 2011 年 IPv4 地址就已經被分配完了,

但是 IPv6 的地址是 128 位的,這可分配的地址數量是大的驚人,說個段子 *IPv6 可以保證地球上的每粒沙子都能被分配到一個 IP 地址*

但 IPv6 除了有更多的地址之外,還有更好的安全性和擴展性,說簡單點就是 IPv6 相比于 IPv4 能帶來更好的網路體驗,

但是因為 IPv4 和 IPv6 不能相互兼容,所以不但要我們電腦、手機之類的設備支持,還需要網路運營商對現有的設備進行升級,所以這可能是 IPv6 普及率比較慢的一個原因,

IPv6 的亮點

IPv6 不僅僅只是可分配的地址變多了,他還有非常多的亮點,

  • IPv6 可自動配置,即使沒有 DHCP 服務器也可以實作自動分配IP地址,真是便捷到即插即用啊,
  • IPv6 包頭包首部長度采用固定的值 40 位元組,去掉了包頭校驗和,簡化了首部結構,減輕了路由器負荷,大大提高了傳輸的性能
  • IPv6 有應對偽造 IP 地址的網路安全功能以及防止線路竊聽的功能,大大提升了安全性
  • (由你發現更多的亮點)

IPv6 地址的標識方法

IPv4 地址長度共 32 位,是以每 8 位作為一組,并用點分十進制的表示方式,

IPv6 地址長度是 128 位,是以每 16 位作為一組,每組用冒號 「:」 隔開,

img

如果出現連續的 0 時還可以將這些 0 省略,并用兩個冒號 「::」隔開,但是,一個 IP 地址中只允許出現一次兩個連續的冒號,

img

IPv6 地址的結構

IPv6 類似 IPv4,也是通過 IP 地址的前幾位標識 IP 地址的種類,

IPv6 的地址主要有一下型別地址:

  • 單播地址,用于一對一的通信
  • 組播地址,用于一對多的通信
  • 任播地址,用于通信最近的節點,最近的節點是由路由協議決定
  • 沒有廣播地址

img

IPv6 單播地址型別

對于一對一通信的 IPv6 地址,主要劃分了三類單播地址,每類地址的有效范圍都不同,

  • 在同一鏈路單播通信,不經過路由器,可以使用鏈路本地單播地址,IPv4 沒有此型別
  • 在內網里單播通信,可以使用唯一本地地址,相當于 IPv4 的私有 IP
  • 在互聯網通信,可以使用全域單播地址,相當于 IPv4 的公有 IP

img

IPv4 首部與 IPv6 首部

IPv4 首部與 IPv6 首部的差異如下圖:

img

IPv6 相比 IPv4 的首部改進:

  • 取消了首部校驗和欄位, 因為在資料鏈路層和傳輸層都會校驗,因此 IPv6 直接取消了 IP 的校驗,
  • 取消了分片/重新組裝相關欄位, 分片與重組是耗時的程序,IPv6 不允許在中間路由器進行分片與重組,這種操作只能在源與目標主機,這將大大提高了路由器轉發的速度,
  • 取消選項欄位, 選項欄位不再是標準 IP 首部的一部分了,但它并沒有消失,而是可能出現在 IPv6 首部中的「下一個首部」指出的位置上,洗掉該選項欄位是的 IPv6 的首部成為固定長度的 40 位元組,

點心 —— IP 協議相關技術

跟 IP 協議相關的技術也不少,接下來說說與 IP 協議相關的重要且常見的技術,

  • DNS 域名決議
  • ARP 與 RARP 協議
  • DHCP 動態獲取 IP 地址
  • NAT 網路地址轉換
  • ICMP 互聯網控制報文協議
  • IGMP 因特網組管理協

DNS

我們在上網的時候,通常使用的方式域名,而不是 IP 地址,因為域名方便人類記憶,

那么實作這一技術的就是 DNS 域名決議,DNS 可以將域名網址自動轉換為具體的 IP 地址,

域名的層級關系

DNS 中的域名都是用句點來分隔的,比如 www.server.com,這里的句點代表了不同層次之間的界限

在域名中,越靠右的位置表示其層級越高

畢竟域名是外國人發明,所以思維和中國人相反,比如說一個城市地點的時候,外國喜歡從小到大的方式順序說起(如 XX 街道 XX 區 XX 市 XX 省),而中國則喜歡從大到小的順序(如 XX 省 XX 市 XX 區 XX 街道),

根域是在最頂層,它的下一層就是 com 頂級域,再下面是 server.com,

所以域名的層級關系類似一個樹狀結構:

  • 根 DNS 服務器
  • 頂級域 DNS 服務器(com)
  • 權威 DNS 服務器(server.com)

img

根域的 DNS 服務器資訊保存在互聯網中所有的 DNS 服務器中,這樣一來,任何 DNS 服務器就都可以找到并訪問根域 DNS 服務器了,

因此,客戶端只要能夠找到任意一臺 DNS 服務器,就可以通過它找到根域 DNS 服務器,然后再一路順藤摸瓜找到位于下層的某臺目標 DNS 服務器,

域名決議的作業流程

瀏覽器首先看一下自己的快取里有沒有,如果沒有就向作業系統的快取要,還沒有就檢查本機域名決議檔案 hosts,如果還是沒有,就會 DNS 服務器進行查詢,查詢的程序如下:

  1. 客戶端首先會發出一個 DNS 請求,問 www.server.com 的 IP 是啥,并發給本地 DNS 服務器(也就是客戶端的 TCP/IP 設定中填寫的 DNS 服務器地址),
  2. 本地域名服務器收到客戶端的請求后,如果快取里的表格能找到 www.server.com,則它直接回傳 IP 地址,如果沒有,本地 DNS 會去問它的根域名服務器:“老大, 能告訴我 www.server.com 的 IP 地址嗎?” 根域名服務器是最高層次的,它不直接用于域名決議,但能指明一條道路,
  3. 根 DNS 收到來自本地 DNS 的請求后,發現后置是 .com,說:“www.server.com 這個域名歸 .com 區域管理”,我給你 .com 頂級域名服務器地址給你,你去問問它吧,”
  4. 本地 DNS 收到頂級域名服務器的地址后,發起請求問“老二, 你能告訴我 www.server.com 的 IP 地址嗎?”
  5. 頂級域名服務器說:“我給你負責 www.server.com 區域的權威 DNS 服務器的地址,你去問它應該能問到”,
  6. 本地 DNS 于是轉向問權威 DNS 服務器:“老三,www.server.com對應的IP是啥呀?” server.com 的權威 DNS 服務器,它是域名決議結果的原出處,為啥叫權威呢?就是我的域名我做主,
  7. 權威 DNS 服務器查詢后將對應的 IP 地址 X.X.X.X 告訴本地 DNS,
  8. 本地 DNS 再將 IP 地址回傳客戶端,客戶端和目標建立連接,

至此,我們完成了 DNS 的決議程序,現在總結一下,整個程序我畫成了一個圖,

img

DNS 域名決議的程序蠻有意思的,整個程序就和我們日常生活中找人問路的程序類似,只指路不帶路

ARP

在傳輸一個 IP 資料報的時候,確定了源 IP 地址和目標 IP 地址后,就會通過主機「路由表」確定 IP 資料包下一跳,然而,網路層的下一層是資料鏈路層,所以我們還要知道「下一跳」的 MAC 地址,

由于主機的路由表中可以找到下一條的 IP 地址,所以可以通過 ARP 協議,求得下一跳的 MAC 地址,

那么 ARP 又是如何知道對方 MAC 地址的呢?

簡單地說,ARP 是借助 ARP 請求與 ARP 回應兩種型別的包確定 MAC 地址的,

img

  • 主機會通過廣播發送 ARP 請求,這個包中包含了想要知道的 MAC 地址的主機 IP 地址,
  • 當同個鏈路中的所有設備收到 ARP 請求時,會去拆開 ARP 請求包里的內容,如果 ARP 請求包中的目標 IP 地址與自己的 IP 地址一致,那么這個設備就將自己的 MAC 地址塞入 ARP 回應包回傳給主機,

作業系統通常會把第一次通過 ARP 獲取的 MAC 地址快取起來,以便下次直接從快取中找到對應 IP 地址的 MAC 地址,

不過,MAC 地址的快取是有一定期限的,超過這個期限,快取的內容將被清除,

RARP 協議你知道是什么嗎?

ARP 協議是已知 IP 地址 求 MAC 地址,那 RARP 協議正好相反,

它是已知 MAC 地址求 IP 地址,例如將列印機服務器等小型嵌入式設備接入到網路時就經常會用得到,

通常這需要架設一臺 RARP 服務器,在這個服務器上注冊設備的 MAC 地址及其 IP 地址,然后再將這個設備接入到網路,接著:

  • 該設備會發送一條「我的 MAC 地址是XXXX,請告訴我,我的IP地址應該是什么」的請求資訊,
  • RARP 服務器接到這個訊息后回傳「MAC地址為 XXXX 的設備,IP地址為 XXXX」的資訊給這個設備,

最后,設備就根據從 RARP 服務器所收到的應答資訊設定自己的 IP 地址,

img

DHCP

DHCP 在生活中我們是很常見的了,我們的電腦通常都是通過 DHCP 動態獲取 IP 地址,大大省去了配 IP 資訊繁瑣的程序,

接下來,我們來看看我們的電腦是如何通過 4 個步驟的程序,獲取到 IP 的,

img

先說明一點,DHCP 客戶端行程監聽的是 68 埠號,DHCP 服務端行程監聽的是 67 埠號,

DHCP 互動的 4 個步驟:

  • 客戶端首先發起 DHCP 發現報文(DHCP DISCOVER) 的 IP 資料報,由于客戶端沒有 IP 地址,也不知道 DHCP 服務器的地址,所以使用的是 UDP 廣播通信,其使用的廣播目的地址是 255.255.255.255(埠 67) 并且使用 0.0.0.0(埠 68) 作為源 IP 地址,DHCP 客戶端將該 IP 資料報傳遞給鏈路層,鏈路層然后將幀廣播到所有的網路中設備,
  • DHCP 服務器收到 DHCP 發現報文時,用 DHCP 提供報文(DHCP OFFER) 向客戶端做出回應,該報文仍然使用 IP 廣播地址 255.255.255.255,該報文資訊攜帶服務器提供可租約的 IP 地址、子網掩碼、默認網關、DNS 服務器以及 IP 地址租用期
  • 客戶端收到一個或多個服務器的 DHCP 提供報文后,從中選擇一個服務器,并向選中的服務器發送 DHCP 請求報文(DHCP REQUEST進行回應,回顯配置的引數,
  • 最后,服務端用 DHCP ACK 報文對 DHCP 請求報文進行回應,應答所要求的引數,

一旦客戶端收到 DHCP ACK 后,互動便完成了,并且客戶端能夠在租用期內使用 DHCP 服務器分配的 IP 地址,

如果租約的 DHCP IP 地址快期后,客戶端會向服務器發送 DHCP 請求報文:

  • 服務器如果同意繼續租用,則用 DHCP ACK 報文進行應答,客戶端就會延長租期,
  • 服務器如果不同意繼續租用,則用 DHCP NACK 報文,客戶端就要停止使用租約的 IP 地址,

可以發現,DHCP 互動中,全程都是使用 UDP 廣播通信

咦,用的是廣播,那如果 DHCP 服務器和客戶端不是在同一個局域網內,路由器又不會轉發廣播包,那不是每個網路都要配一個 DHCP 服務器?

所以,為了解決這一問題,就出現了 DHCP 中繼代理

有了 DHCP 中繼代理以后,對不同網段的 IP 地址分配也可以由一個 DHCP 服務器統一進行管理,

img

  • DHCP 客戶端會向 DHCP 中繼代理發送 DHCP 請求包,而 DHCP 中繼代理在收到這個廣播包以后,再以單播的形式發給 DHCP 服務器,
  • 服務器端收到該包以后再向 DHCP 中繼代理回傳應答,并由 DHCP 中繼代理將此包轉發給 DHCP 客戶端 ,

因此,DHCP 服務器即使不在同一個鏈路上也可以實作統一分配和管理IP地址,

NAT

IPv4 的地址是非常緊缺的,在前面我們也提到可以通過無分類地址來級訓 IPv4 地址耗盡的速度,但是互聯網的用戶增速是非常驚人的,所以 IPv4 地址依然有被耗盡的危險,

于是,提出了一個種網路地址轉換 NAT 的方法,再次緩解了 IPv4 地址耗盡的問題,

簡單的來說 NAT 就是在同個公司、家庭、教室內的主機對外部通信時,把私有 IP 地址轉換成公有 IP 地址,

img

那不是 N 個 私有 IP 地址,你就要 N 個公有 IP 地址?這怎么就緩解了 IPv4 地址耗盡的問題?這不瞎扯嗎?

確實是,普通的 NAT 轉換沒什么意義,

由于絕大多數的網路應用都是使用傳輸層協議 TCP 或 UDP 來傳輸資料的,

因此,可以把 IP 地址 + 埠號一起進行轉換,

這樣,就用一個全球 IP 地址就可以了,這種轉換技術就叫網路地址與埠轉換 NAPT,

很抽象?來,看下面的圖解就能瞬間明白了,

img

圖中有兩個客戶端 192.168.1.10 和 192.168.1.11 同時與服務器 183.232.231.172 進行通信,并且這兩個客戶端的本地埠都是 1025,

此時,*兩個私有 IP 地址都轉換 IP 地址為公有地址 120.229.175.121,但是以不同的埠號作為區分*

于是,生成一個 NAPT 路由器的轉換表,就可以正確地轉換地址跟埠的組合,令客戶端 A、B 能同時與服務器之間進行通信,

這種轉換表在 NAT 路由器上自動生成,例如,在 TCP 的情況下,建立 TCP 連接首次握手時的 SYN 包一經發出,就會生成這個表,而后又隨著收到關閉連接時發出 FIN 包的確認應答從表中被洗掉,

NAT 那么牛逼,難道就沒缺點了嗎?

當然有缺陷,肯定沒有十全十美的方案,

由于 NAT/NAPT 都依賴于自己的轉換表,因此會有以下的問題:

  • 外部無法主動與 NAT 內部服務器建立連接,因為 NAPT 轉換表沒有轉換記錄,
  • 轉換表的生產與轉換操作都會產生性能開銷,
  • 通信程序中,如果 NAT 路由器重啟了,所有的 TCP 連接都將被重置,

如何解決 NAT 潛在的問題呢?

解決的方法主要兩種方法,

第一種就是改用 IPv6

IPv6 可用范圍非常大,以至于每臺設備都可以配置一個公有 IP 地址,就不搞那么多花里胡哨的地址轉換了,但是 IPv6 普及速度還需要一些時間,

第二種 NAT 穿透技術

NAT 穿越技術擁有這樣的功能,它能夠讓網路應用程式主動發現自己位于 NAT 設備之后,并且會主動獲得 NAT 設備的公有 IP,并為自己建立埠映射條目,注意這些都是 NAT設備后的應用程式自動完成的,

也就是說,在 NAT 穿越技術中,NAT 設備后的應用程式處于主動地位,它已經明確地知道 NAT 設備要修改它外發的資料包,于是它主動配合 NAT 設備的操作,主動地建立好映射,這樣就不像以前由 NAT 設備來建立映射了,

說人話,就是客戶端主動從 NAT 設備獲取公有 IP 地址,然后自己建立埠映射條目,然后用這個條目對外通信,就不需要 NAT 設備來進行轉換了,

ICMP

ICMP 全稱是 Internet Control Message Protocol,也就是互聯網控制報文協議

里面有個關鍵詞 —— 控制,如何控制的呢?

網路包在復雜的網路傳輸環境里,常常會遇到各種問題,

當遇到問題的時候,總不能死個不明不白,沒頭沒腦的作風不是計算機網路的風格,所以需要傳出訊息,報告遇到了什么問題,這樣才可以調整傳輸策略,以此來控制整個局面,

ICMP 功能都有啥?

ICMP 主要的功能包括:*確認 IP 包是否成功送達目標地址、報告發送程序中 IP 包被廢棄的原因和改善網路設定等*

IP 通信中如果某個 IP 包因為某種原因未能達到目標地址,那么這個具體的原因將由 ICMP 負責通知

img

如上圖例子,主機 A 向主機 B 發送了資料包,由于某種原因,途中的路由器 2 未能發現主機 B 的存在,這時,路由器 2 就會向主機 A 發送一個 ICMP 目標不可達資料包,說明發往主機 B 的包未能成功,

ICMP 的這種通知訊息會使用 IP 進行發送 ,

因此,從路由器 2 回傳的 ICMP 包會按照往常的路由控制先經過路由器 1 再轉發給主機 A ,收到該 ICMP 包的主機 A 則分解 ICMP 的首部和資料域以后得知具體發生問題的原因,

ICMP 型別

ICMP 大致可以分為兩大類:

  • 一類是用于診斷的查詢訊息,也就是「查詢報文型別
  • 另一類是通知出錯原因的錯誤訊息,也就是「差錯報文型別

img

IGMP

ICMP 跟 IGMP 是一點關系都沒有的,就好像周杰與周杰倫的區別,大家不要混淆了,

在前面我們知道了組播地址,也就是 D 類地址,既然是組播,那就說明是只有一組的主機能收到資料包,不在一組的主機不能收到陣列包,怎么管理是否是在一組呢?那么,就需要 IGMP 協議了,

img

IGMP 是因特網組管理協議,作業在主機(組播成員)和最后一跳路由之間,如上圖中的藍色部分,

  • IGMP 報文向路由器申請加入和退出組播組,默認情況下路由器是不會轉發組播包到連接中的主機,除非主機通過 IGMP 加入到組播組,主機申請加入到組播組時,路由器就會記錄 IGMP 路由器表,路由器后續就會轉發該組播地址的資料包了,
  • IGMP 報文采用 IP 封裝,IP 頭部的協議號為 2,而且 TTL 欄位值通常 為 1,因為 IGMP 是作業在主機與連接的路由器之間,

IGMP 作業機制

IGMP 分為了三個版本分別是,IGMPv1、IGMPv2、IGMPv3,

接下來,以 IGMPv2 作為例子,說說常規查詢與回應和離開組播組這兩個作業機制,

常規查詢與回應作業機制

img

  1. 路由器會周期性發送目的地址為 224.0.0.1(表示同一網段內所有主機和路由器) *IGMP 常規查詢報文*
  2. 主機1 和 主機 3 收到這個查詢,隨后會啟動「報告延遲計時器」,計時器的時間是隨機的,通常是 0~10 秒,計時器超時后主機就會發送 IGMP 成員關系報告報文(源 IP 地址為自己主機的 IP 地址,目的 IP 地址為組播地址),如果在定時器超時之前,收到同一個組內的其他主機發送的成員關系報告報文,則自己不再發送,這樣可以減少網路中多余的 IGMP 報文數量;
  3. 路由器收到主機的成員關系報告報文后,就會在 IGMP 路由表中加入該組播組,后續網路中一旦該組播地址的資料到達路由器,它會把資料包轉發出去;

離開組播組作業機制

離開組播組的情況一,網段中仍有該組播組:

img

  1. 主機 1 要離開組 224.1.1.1,發送 IGMPv2 離組報文,報文的目的地址是 224.0.0.2(表示發向網段內的所有路由器);
  2. 路由器收到該報文后,以 1 秒為間隔連續發送 IGMP 特定組查詢報文(共計發送 2 個),以便確認該網路是否還有 224.1.1.1 組的其他成員;
  3. 主機 3 仍然是組 224.1.1.1 的成員,因此它立即回應這個特定組查詢,路由器知道該網路中仍然存在該組播組的成員,于是繼續向該網路轉發 224.1.1.1 的組播資料包;

離開組播組的情況二,網段中沒有該組播組:

img

  • 主機 1 要離開組播組 224.1.1.1,發送 IGMP 離組報文;
  • 路由器收到該報文后,以 1 秒為間隔連續發送 IGMP 特定組查詢報文(共計發送 2 個),此時在該網段內,組 224.1.1.1 已經沒有其他成員了,因此沒有主機回應這個查詢;
  • 一定時間后,路由器認為該網段中已經沒有 224.1.1.1 組播組成員了,將不會再向這個網段轉發該組播地址的資料包;

參考文獻

[1] 計算機網路-自頂向下方法.陳鳴 譯.機械工業出版社

[2] TCP/IP詳解 卷1:協議.范建華 譯.機械工業出版社

[3] 圖解TCP/IP.竹下隆史.人民郵電出版社

歡迎關注公眾號 【碼農開花】一起學習成長
我會一直分享Java干貨,也會分享免費的學習資料課程和面試寶典
回復:【計算機】【設計模式】【面試】有驚喜哦

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/249319.html

標籤:Java

上一篇:Spring Boot 集成 JUnit5,更優雅單元測驗!

下一篇:Netty 系列之 Netty 百萬級推送服務設計要點

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more