你是一臺電腦,你的名字叫 A
很久很久之前,你不與任何其他電腦相連接,孤苦伶仃。
直到有一天,你希望與另一臺電腦 B 建立通信,于是你們各開了一個網口,用一根網線連接了起來。
用一根網線連接起來怎么就能“通信”了呢?我可以給你講 IO、講中斷、講緩沖區,但這不是研究網絡時該關心的問題。
如果你糾結,要么去研究一下操作系統是如何處理網絡 IO 的,要么去研究一下包是如何被網卡轉換成電信號發送出去的,要么就僅僅把它當做電腦里有個小人在開槍吧~
反正,你們就是連起來了,并且可以通信。
第一層
有一天,一個新伙伴 C 加入了,但聰明的你們很快發現,可以每個人開兩個網口,用一共三根網線,彼此相連。
隨著越來越多的人加入,你發現身上開的網口實在太多了,而且網線密密麻麻,混亂不堪。(而實際上一臺電腦根本開不了這么多網口,所以這種連線只在理論上可行,所以連不上的我就用紅色虛線表示了,就是這么嚴謹哈哈~)
于是你們發明了一個中間設備,你們將網線都插到這個設備上,由這個設備做轉發,就可以彼此之間通信了,本質上和原來一樣,只不過網口的數量和網線的數量減少了,不再那么混亂。
你給它取名叫集線器,它僅僅是無腦將電信號轉發到所有出口(廣播),不做任何處理,你覺得它是沒有智商的,因此把人家定性在了物理層。
由于轉發到了所有出口,那 BCDE 四臺機器怎么知道數據包是不是發給自己的呢?
首先,你要給所有的連接到集線器的設備,都起個名字。原來你們叫 ABCD,但現在需要一個更專業的,全局唯一的名字作為標識,你把這個更高端的名字稱為 MAC 地址。
你的 MAC 地址是 aa-aa-aa-aa-aa-aa,你的伙伴 b 的 MAC 地址是 bb-bb-bb-bb-bb-bb,以此類推,不重復就好。
這樣,A 在發送數據包給 B 時,只要在頭部拼接一個這樣結構的數據,就可以了。
B 在收到數據包后,根據頭部的目標 MAC 地址信息,判斷這個數據包的確是發給自己的,于是便收下。
其他的 CDE 收到數據包后,根據頭部的目標 MAC 地址信息,判斷這個數據包并不是發給自己的,于是便丟棄。
雖然集線器使整個布局干凈不少,但原來我只要發給電腦 B 的消息,現在卻要發給連接到集線器中的所有電腦,這樣既不安全,又不節省網絡資源。
第二層
如果把這個集線器弄得更智能一些,只發給目標 MAC 地址指向的那臺電腦,就好了。
雖然只比集線器多了這一點點區別,但看起來似乎有智能了,你把這東西叫做交換機。也正因為這一點點智能,你把它放在了另一個層級,數據鏈路層。
如上圖所示,你是這樣設計的。
交換機內部維護一張 MAC 地址表,記錄著每一個 MAC 地址的設備,連接在其哪一個端口上。
MAC 地址端口
bb-bb-bb-bb-bb-bb1
cc-cc-cc-cc-cc-cc3
aa-aa-aa-aa-aa-aa4
dd-dd-dd-dd-dd-dd5
假如你仍然要發給 B 一個數據包,構造了如下的數據結構從網口出去。
到達交換機時,交換機內部通過自己維護的 MAC 地址表,發現目標機器 B 的 MAC 地址 bb-bb-bb-bb-bb-bb 映射到了端口 1 上,于是把數據從 1 號端口發給了 B,完事~
你給這個通過這樣傳輸方式而組成的小范圍的網絡,叫做以太網。
當然最開始的時候,MAC 地址表是空的,是怎么逐步建立起來的呢?
假如在 MAC 地址表為空是,你給 B 發送了如下數據:
由于這個包從端口 4 進入的交換機,所以此時交換機就可以在 MAC地址表記錄第一條數據:
MAC:aa-aa-aa-aa-aa-aa-aa
端口:4
交換機看目標 MAC 地址(bb-bb-bb-bb-bb-bb)在地址表中并沒有映射關系,于是將此包發給了所有端口,也即發給了所有機器。
之后,只有機器 B 收到了確實是發給自己的包,于是做出了響應,響應數據從端口 1 進入交換機,于是交換機此時在地址表中更新了第二條數據:
MAC:bb-bb-bb-bb-bb-bb
端口:1
過程如下:
經過該網絡中的機器不斷地通信,交換機最終將 MAC 地址表建立完畢~
隨著機器數量越多,交換機的端口也不夠了,但聰明的你發現,只要將多個交換機連接起來,這個問題就輕而易舉搞定~
你完全不需要設計額外的東西,只需要按照之前的設計和規矩來,按照上述的接線方式即可完成所有電腦的互聯,所以交換機設計的這種規則,真的很巧妙。你想想看為什么(比如 A 要發數據給 F)。
但是你要注意,上面那根紅色的線,最終在 MAC 地址表中可不是一條記錄呀,而是要把 EFGH 這四臺機器與該端口(端口6)的映射全部記錄在表中。
最終,兩個交換機將分別記錄 A ~ H 所有機器的映射記錄。
左邊的交換機
MAC 地址端口
bb-bb-bb-bb-bb-bb1
cc-cc-cc-cc-cc-cc3
aa-aa-aa-aa-aa-aa4
dd-dd-dd-dd-dd-dd5
ee-ee-ee-ee-ee-ee6
ff-ff-ff-ff-ff-ff6
gg-gg-gg-gg-gg-gg6
hh-hh-hh-hh-hh-hh6
右邊的交換機
MAC 地址端口
bb-bb-bb-bb-bb-bb1
cc-cc-cc-cc-cc-cc1
aa-aa-aa-aa-aa-aa1
dd-dd-dd-dd-dd-dd1
ee-ee-ee-ee-ee-ee2
ff-ff-ff-ff-ff-ff3
gg-gg-gg-gg-gg-gg4
hh-hh-hh-hh-hh-hh6
這在只有 8 臺電腦的時候還好,甚至在只有幾百臺電腦的時候,都還好,所以這種交換機的設計方式,已經足足支撐一陣子了。
但很遺憾,人是貪婪的動物,很快,電腦的數量就發展到幾千、幾萬、幾十萬。
第三層
交換機已經無法記錄如此龐大的映射關系了。
此時你動了歪腦筋,你發現了問題的根本在于,連出去的那根紅色的網線,后面不知道有多少個設備不斷地連接進來,從而使得地址表越來越大。
那我可不可以讓那根紅色的網線,接入一個新的設備,這個設備就跟電腦一樣有自己獨立的 MAC 地址,而且同時還能幫我把數據包做一次轉發呢?
這個設備就是路由器,它的功能就是,作為一臺獨立的擁有 MAC 地址的設備,并且可以幫我把數據包做一次轉發,你把它定在了網絡層。
注意,路由器的每一個端口,都有獨立的 MAC 地址。
好了,現在交換機的 MAC 地址表中,只需要多出一條 MAC 地址 ABAB 與其端口的映射關系,就可以成功把數據包轉交給路由器了,這條搞定。
那如何做到,把發送給 C 和 D,甚至是把發送給 DEFGH.。.. 的數據包,統統先發送給路由器呢?
不難想到這樣一個點子,假如電腦 C 和 D 的 MAC 地址擁有共同的前綴,比如分別是:
C 的 MAC 地址:FFFF-FFFF-CCCCD 的 MAC 地址:FFFF-FFFF-DDDD
那我們就可以說,將目標 MAC 地址為 FFFF-FFFF-?開頭的,統統先發送給路由器。
這樣是否可行呢?答案是否定的。
我們先從現實中 MAC 地址的結構入手,MAC地址也叫物理地址、硬件地址,長度為 48 位,一般這樣來表示:
00-16-EA-AE-3C-40
它是由網絡設備制造商生產時燒錄在網卡的EPROM(一種閃存芯片,通常可以通過程序擦寫)。其中前 24 位(00-16-EA)代表網絡硬件制造商的編號,后 24 位(AE-3C-40)是該廠家自己分配的,一般表示系列號。只要不更改自己的 MAC 地址,MAC 地址在世界是唯一的。形象地說,MAC地址就如同身份證上的身份證號碼,具有唯一性。
那如果你希望向上面那樣將目標 MAC 地址表示為 FFFF-FFFF-?開頭的,統一從路由器出去發給某一群設備(后面會提到這其實是子網的概念),那你就需要要求某一子網下統統買一個廠商制造的設備,要么你就需要要求廠商在生產網絡設備燒錄 MAC 地址時,提前按照你規劃好的子網結構來定 MAC 地址,并且日后這個網絡的結構都不能輕易改變。
這顯然是不現實的。
于是你發明了一個新的地址,給每一臺機器一個 32 位的編號,如:
11000000101010000000000000000001
你覺得有些不清晰,于是把它分成四個部分,中間用點相連。
11000000.10101000.00000000.00000001
你還覺得不清晰,于是把它轉換成 10 進制。
192.168.0.1
最后你給了這個地址一個響亮的名字,IP 地址。現在每一臺電腦,同時有自己的 MAC 地址,又有自己的 IP 地址,只不過 IP 地址是軟件層面上的,可以隨時修改,MAC 地址一般是無法修改的。
這樣一個可以隨時修改的 IP 地址,就可以根據你規劃的網絡拓撲結構,來調整了。
如上圖所示,假如我想要發送數據包給 ABCD 其中一臺設備,不論哪一臺,我都可以這樣描述,“將 IP 地址為 192.168.0 開頭的全部發送給到路由器,之后再怎么轉發,交給它!”,巧妙吧。
那交給路由器之后,路由器又是怎么把數據包準確轉發給指定設備的呢?
別急我們慢慢來。
我們先給上面的組網方式中的每一臺設備,加上自己的 IP 地址。
現在兩個設備之間傳輸,除了加上數據鏈路層的頭部之外,還要再增加一個網絡層的頭部。
假如 A 給 B 發送數據,由于它們直接連著交換機,所以 A 直接發出如下數據包即可,其實網絡層沒有體現出作用。
但假如 A 給 C 發送數據,A 就需要先轉交給路由器,然后再由路由器轉交給 C。由于最底層的傳輸仍然需要依賴以太網,所以數據包是分成兩段的。
A ~ 路由器這段的包如下:
路由器到 C 這段的包如下:
好了,上面說的兩種情況(A-》B,A-》C),相信細心的讀者應該會有不少疑問,下面我們一個個來展開。
A 給 C 發數據包,怎么知道是否要通過路由器轉發呢?
答案:子網
如果源 IP 與目的 IP 處于一個子網,直接將包通過交換機發出去。
如果源 IP 與目的 IP 不處于一個子網,就交給路由器去處理。
好,那現在只需要解決,什么叫處于一個子網就好了。
192.168.0.1 和 192.168.0.2 處于同一個子網
192.168.0.1 和 192.168.1.1 處于不同子網這兩個是我們人為規定的,即我們想表示,對于 192.168.0.1 來說:
192.168.0.xxx 開頭的,就算是在一個子網,否則就是在不同的子網。
那對于計算機來說,怎么表達這個意思呢?于是人們發明了子網掩碼的概念。
假如某臺機器的子網掩碼定為 255.255.255.0。
這表示,將源 IP 與目的 IP 分別同這個子網掩碼進行與運算,相等則是在一個子網,不相等就是在不同子網,就這么簡單。
比如:
A電腦:192.168.0.1 & 255.255.255.0 = 192.168.0.0
B電腦:192.168.0.2 & 255.255.255.0 = 192.168.0.0
C電腦:192.168.1.1 & 255.255.255.0 = 192.168.1.0
D電腦:192.168.1.2 & 255.255.255.0 = 192.168.1.0那么 A 與 B 在同一個子網,C 與 D 在同一個子網,但是 A 與 C 就不在同一個子網,與 D 也不在同一個子網,以此類推。
所以如果 A 給 C 發消息,A 和 C 的 IP 地址分別 & A 機器配置的子網掩碼,發現不相等,則 A 認為 C 和自己不在同一個子網,于是把包發給路由器,就不管了,之后怎么轉發,A 不關心。
A 如何知道,哪個設備是路由器?
答案:在 A 上要設置默認網關
上一步 A 通過是否與 C 在同一個子網內,判斷出自己應該把包發給路由器,那路由器的 IP 是多少呢?
其實說發給路由器不準確,應該說 A 會把包發給默認網關。
對 A 來說,A 只能直接把包發給同處于一個子網下的某個 IP 上,所以發給路由器還是發給某個電腦,對 A 來說也不關心,只要這個設備有個 IP 地址就行。
所以默認網關,就是 A 在自己電腦里配置的一個 IP 地址,以便在發給不同子網的機器時,發給這個 IP 地址。
僅此而已!
路由器如何知道C在哪里?
答案:路由表
現在 A 要給 C 發數據包,已經可以成功發到路由器這里了,最后一個問題就是,路由器怎么知道,收到的這個數據包,該從自己的哪個端口出去,才能直接(或間接)地最終到達目的地 C 呢。
路由器收到的數據包有目的 IP 也就是 C 的 IP 地址,需要轉化成從自己的哪個端口出去,很容易想到,應該有個表,就像 MAC 地址表一樣。
這個表就叫路由表。
至于這個路由表是怎么出來的,有很多路由算法,本文不展開,因為我也不會哈哈~
不同于 MAC 地址表的是,路由表并不是一對一這種明確關系,我們下面看一個路由表的結構。
目的地址子網掩碼下一跳端口
192.168.0.0255.255.255.0
0
192.168.0.254255.255.255.255
0
192.168.1.0255.255.255.0
1
192.168.1.254255.255.255.255
1
我們學習一種新的表示方法,由于子網掩碼其實就表示前多少位表示子網的網段,所以如 192.168.0.0(255.255.255.0) 也可以簡寫為 192.168.0.0/24。
目的地址下一跳端口
192.168.0.0/24
0
192.168.0.254/32
0
192.168.1.0/24
1
192.168.1.254/32
1
這就很好理解了,路由表就表示,192.168.0.xxx 這個子網下的,都轉發到 0 號端口,192.168.1.xxx 這個子網下的,都轉發到 1 號端口。下一跳列還沒有值,我們先不管。
配合著結構圖來看(這里把子網掩碼和默認網關都補齊了)圖中 & 筆誤,結果應該是 .0
剛才說的都是 IP 層,但發送數據包的數據鏈路層需要知道 MAC 地址,可是我只知道 IP 地址該怎么辦呢?
答案:arp
假如你(A)此時不知道你同伴 B 的 MAC 地址(現實中就是不知道的,剛剛我們只是假設已知),你只知道它的 IP 地址,你該怎么把數據包準確傳給 B 呢?
答案很簡單,在網絡層,我需要把 IP 地址對應的 MAC 地址找到,也就是通過某種方式,找到 192.168.0.2 對應的 MAC 地址 BBBB。
這種方式就是 arp 協議,同時電腦 A 和 B 里面也會有一張 arp 緩存表,表中記錄著 IP 與 MAC 地址的對應關系。
IP 地址MAC 地址
192.168.0.2BBBB
一開始的時候這個表是空的,電腦 A 為了知道電腦 B(192.168.0.2)的 MAC 地址,將會廣播一條 arp 請求,B 收到請求后,帶上自己的 MAC 地址給 A 一個響應。此時 A 便更新了自己的 arp 表。
這樣通過大家不斷廣播 arp 請求,最終所有電腦里面都將 arp 緩存表更新完整。
總結一下
好了,總結一下,到目前為止就幾條規則:
從各個節點的視角來看
電腦視角:
首先我要知道我的 IP 以及對方的 IP
通過子網掩碼判斷我們是否在同一個子網
在同一個子網就通過 arp 獲取對方 mac 地址直接扔出去
不在同一個子網就通過 arp 獲取默認網關的 mac 地址直接扔出去
交換機視角:
我收到的數據包必須有目標 MAC 地址
通過 MAC 地址表查映射關系
查到了就按照映射關系從我的指定端口發出去
查不到就所有端口都發出去路由器視角:
我收到的數據包必須有目標 IP 地址
通過路由表查映射關系
查到了就按照映射關系從我的指定端口發出去(不在任何一個子網范圍,走其路由器的默認網關也是查到了)
查不到則返回一個路由不可達的數據包如果你嗅覺足夠敏銳,你應該可以感受到下面這句話:
網絡層(IP協議)本身沒有傳輸包的功能,包的實際傳輸是委托給數據鏈路層(以太網中的交換機)來實現的。
涉及到的三張表分別是
交換機中有 MAC 地址表用于映射 MAC 地址和它的端口
路由器中有路由表用于映射 IP 地址(段)和它的端口
電腦和路由器中都有 arp 緩存表用于緩存 IP 和 MAC 地址的映射關系
這三張表是怎么來的
MAC 地址表是通過以太網內各節點之間不斷通過交換機通信,不斷完善起來的。
路由表是各種路由算法 + 人工配置逐步完善起來的。
arp 緩存表是不斷通過 arp 協議的請求逐步完善起來的。
知道了以上這些,目前網絡上兩個節點是如何發送數據包的這個過程,就完全可以解釋通了!
那接下來我們就放上本章 最后一個 網絡拓撲圖吧,請做好 戰斗 準備!
這時路由器 1 連接了路由器 2,所以其路由表有了下一條地址這一個概念,所以它的路由表就變成了這個樣子。如果匹配到了有下一跳地址的一項,則需要再次匹配,找到其端口,并找到下一跳 IP 的 MAC 地址。
也就是說找來找去,最終必須能映射到一個端口號,然后從這個端口號把數據包發出去。
目的地址下一跳端口
192.168.0.0/24
0
192.168.0.254/32
0
192.168.1.0/24
1
192.168.1.254/32
1
192.168.2.0/24192.168.100.5
192.168.100.0/24
2
192.168.100.4/32
2
這時如果 A 給 F 發送一個數據包,能不能通呢?如果通的話整個過程是怎樣的呢?
思考一分鐘。..
詳細過程動畫描述
詳細過程文字描述:
1. 首先 A(192.168.0.1)通過子網掩碼(255.255.255.0)計算出自己與 F(192.168.2.2)并不在同一個子網內,于是決定發送給默認網關(192.168.0.254)。2. A 通過 ARP 找到 默認網關 192.168.0.254 的 MAC 地址。3. A 將源 MAC 地址(AAAA)與網關 MAC 地址(ABAB)封裝在數據鏈路層頭部,又將源 IP 地址(192.168.0.1)和目的 IP 地址(192.168.2.2)(注意這里千萬不要以為填寫的是默認網關的 IP 地址,從始至終這個數據包的兩個 IP 地址都是不變的,只有 MAC 地址在不斷變化)封裝在網絡層頭部,然后發包。
4. 交換機 1 收到數據包后,發現目標 MAC 地址是 ABAB,轉發給路由器 1。5. 數據包來到了路由器 1,發現其目標 IP 地址是 192.168.2.2,查看其路由表,發現了下一跳的地址是 192.168.100.5。6. 所以此時路由器 1 需要做兩件事,第一件是再次匹配路由表,發現匹配到了端口為 2,于是將其封裝到數據鏈路層,最后把包從 2 號口發出去。7. 此時路由器 2 收到了數據包,看到其目的地址是 192.168.2.2,查詢其路由表,匹配到端口號為 1,準備從 1 號口把數據包送出去。8. 但此時路由器 2 需要知道 192.168.2.2 的 MAC 地址了,于是查看其 arp 緩存,找到其 MAC 地址為 FFFF,將其封裝在數據鏈路層頭部,并從 1 號端口把包發出去。9. 交換機 3 收到了數據包,發現目的 MAC 地址為 FFFF,查詢其 MAC 地址表,發現應該從其 6 號端口出去,于是從 6 號端口把數據包發出去。10. F 最終收到了數據包!并且發現目的 MAC 地址就是自己,于是收下了這個包。
后記
至此,經過物理層、數據鏈路層、網絡層這前三層的協議,以及根據這些協議設計的各種網絡設備(網線、集線器、交換機、路由器),理論上只要擁有對方的 IP 地址,就已經將地球上任意位置的兩個節點連通了。
責任編輯:haq
-
通信
+關注
關注
18文章
6024瀏覽量
135950 -
計算機
+關注
關注
19文章
7488瀏覽量
87854 -
網路
+關注
關注
0文章
12瀏覽量
8535
原文標題:如果讓你來設計網絡,你會把它弄成啥樣?
文章出處:【微信號:DBDevs,微信公眾號:數據分析與開發】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論