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

計算機網(wǎng)絡協(xié)議介紹

計算機網(wǎng)絡架構的演進
云端超級計算機使用教程
量子計算機與普通計算機工作原理的區(qū)別

評論