來源丨經(jīng)授權(quán)轉(zhuǎn)自 古時的風(fēng)箏(ID:gushidefengzheng) 我們?nèi)绻斫鈹?shù)據(jù)是如果在網(wǎng)絡(luò)世界中穿梭的,那其實只要了解其中的三張表就可以了,。這三張表分別為路由表,、轉(zhuǎn)發(fā)表、ARP 表,。 假設(shè)我們用聊天工具聊天的時候,,我在北京,你在廣東,,當我給你發(fā)送一條消息的時候。搭載這這條消息的數(shù)據(jù)包需要從我的設(shè)備(電腦或手機)出發(fā),,跨域千上萬水,,趟過萬里光纖,在不出意外的情況下才能到達你的設(shè)備,。在這個過程中數(shù)據(jù)包要經(jīng)過大致流程如下: 1,、數(shù)據(jù)在我的設(shè)備上從應(yīng)用層向下層層封裝,最后發(fā)送到路由設(shè)備上,; 2,、路由設(shè)備對數(shù)據(jù)包進行轉(zhuǎn)發(fā),可能經(jīng)過不止一個路由器和交換機,; 3,、終于到達你的設(shè)備所在的子網(wǎng)路由器,你所在的子網(wǎng)路由器轉(zhuǎn)發(fā)給局域網(wǎng)內(nèi)所有的直接相連的主機或交換機,,如果是轉(zhuǎn)發(fā)給交換機的話,,交換機再次轉(zhuǎn)發(fā)給交換機上連接的設(shè)備; 4,、當你的設(shè)備發(fā)現(xiàn)這個數(shù)據(jù)包的目的主機是自己,,就開始對數(shù)據(jù)包進行自鏈路層向上的一層一層的解封裝,最終由對應(yīng)的應(yīng)用程序拿到消息,; 主要的流程就是這樣,,但是中間每一種設(shè)備的轉(zhuǎn)發(fā)都有對應(yīng)的規(guī)則,主要涉及的設(shè)備就是終端,、交換機,、路由器,接下來我們具體來梳理一下一個數(shù)據(jù)包這一路上是怎么跋山涉水才呈現(xiàn)到你的屏幕上的,。 跋山涉水來找你看下圖,,假設(shè)現(xiàn)在「子網(wǎng)A的主機A」要發(fā)一條消息給「子網(wǎng)B的主機x-1」,這兩個主機分別在不同的子網(wǎng),,也就是說并不是局域網(wǎng)內(nèi)的傳輸,,中間經(jīng)過了路由器A、路由器B、子網(wǎng)B的頂層交換機,、交換機X,,最終才到達了目標主機X-1。 主機A封裝數(shù)據(jù)包并發(fā)送如果你已經(jīng)掌握了傳輸層,、網(wǎng)絡(luò)層,、鏈路層的各個協(xié)議,那這個過程就相對來說非常簡單了,。 應(yīng)用層某聊天工具發(fā)送消息,,消息內(nèi)容被處理之后,也就是上圖中的用戶數(shù)據(jù),。 經(jīng)過傳輸層,,使用 TCP 協(xié)議傳輸,TCP 將用戶數(shù)據(jù)封裝上 TCP 首部信息,,形成一個 TCP 段,。注意了,TCP 首部中含有源端口號和目標端口號,,應(yīng)用層會根據(jù)端口號決定哪個應(yīng)用程序使用這個包,。比如我們自己開發(fā)的聊天程序,端口用的是 18888,,那這個包到達主機X-1之后,,發(fā)現(xiàn) TCP 協(xié)議頭中的端口號是 18888,那就知道要把這個包交給我們開發(fā)的聊天工具處理了,。 經(jīng)過網(wǎng)絡(luò)層,,搭載IP協(xié)議,在TCP段的基礎(chǔ)上,,加上IP首部信息,,形成IP數(shù)據(jù)報。注意了,,IP首部含有源IP地址和目的IP地址,,要不然網(wǎng)海茫茫,誰來接收它,,它又回復(fù)誰呢,。在這個 IP 數(shù)據(jù)報中,源IP就是主機A的IP,,目的 IP 地址就是主機X-1的IP,。 最后經(jīng)過鏈路層,在IP數(shù)據(jù)報的基礎(chǔ)上,,加上以太網(wǎng)幀首部,,形成以太網(wǎng)幀數(shù)據(jù)包,。在以太網(wǎng)上,只有以太網(wǎng)幀能順利通行,。注意了,,以太網(wǎng)幀首部包含源MAC地址和目的MAC地址,鏈路層只認MAC地址,,有了它才能找到對應(yīng)的終端,。 經(jīng)過層層包裝后,真正跑到以太網(wǎng)上的數(shù)據(jù)最終必須是一個完整的以太網(wǎng)幀,,而以太網(wǎng)幀中必須要有目的端的 MAC 地址,。接下來就是怎么拿到目的端的 MAC地址了。 當發(fā)送端開始組裝數(shù)據(jù)的時候,,首先會檢查目的IP 和自身的IP 是否處在同一個網(wǎng)絡(luò)中,。計算方式很簡單,就是用 IP 地址和子網(wǎng)掩碼進行「與運算」,。 如果目的端在局域網(wǎng)內(nèi)如果得到的網(wǎng)絡(luò)地址是一致的,說明在同一個網(wǎng)絡(luò)中,。 這時,,ARP表就要上場了。 ARP 表記錄著 IP 地址和 MAC 地址的映射關(guān)系,??梢愿鶕?jù) IP 地址查到對應(yīng)的 MAC 地址,然后放到以太網(wǎng)幀中,,如果有的話,。 發(fā)送端檢查自己的 ARP 表中是否有目的 IP 對應(yīng)的 MAC 地址。如果有的話,,直接將 MAC 地址組裝到以太網(wǎng)數(shù)據(jù)幀中,,發(fā)送數(shù)據(jù)幀,數(shù)據(jù)就能被目的端順利接收,。如果ARP 表中不存在目的IP對應(yīng)的 MAC 地址,,則向本網(wǎng)絡(luò)廣播發(fā)送 ARP 請求,ARP 請求會帶著目的IP地址,,意思就是詢問“誰的IP地址是這個,,請回復(fù)你的MAC地址給我”,網(wǎng)絡(luò)中的主機看到后,,如果IP是自己的,,就返回給發(fā)送端一個ARP回復(fù),回復(fù)中帶著自己的MAC地址,,發(fā)送端拿到MAC地址后,,先存入本地的ARP表,然后組裝以太網(wǎng)幀,將數(shù)據(jù)發(fā)送,。 如果目的端不在局域網(wǎng)內(nèi)如果得到的網(wǎng)絡(luò)地址不一致,,說明目的端不在本網(wǎng)絡(luò)中。那這樣的話,,查詢 ARP表是不可能查到對應(yīng)的 MAC 地址的,,因為 ARP 表只存儲局域網(wǎng)內(nèi)的 IP 和 MAC 地址的映射記錄。 既然查不到那怎么辦,,總得發(fā)出去才行啊,。 如果 ARP 表中查不到記錄,那只能走默認網(wǎng)關(guān)了,。我們的設(shè)備都是知道默認網(wǎng)關(guān)的 IP地址的,,這時候再去 ARP 表查詢是否有網(wǎng)關(guān)地址對應(yīng)的 MAC 地址,如果有直接將網(wǎng)關(guān)的 MAC 地址封裝到以太網(wǎng)幀的目的地址中,。如果沒有的話,,仍然要像上面那樣,廣播發(fā)送 ARP 請求,,獲取網(wǎng)關(guān)設(shè)備的 MAC 地址,,然后存入 ARP 表中。對應(yīng)到上圖就是路由器A的端口1的網(wǎng)卡地址,。 那將網(wǎng)關(guān)的 MAC 地址當做目的 MAC 地址,,還怎么找到最終的目的端啊,最終的消息也不是想發(fā)給網(wǎng)關(guān)啊,。 沒辦法,,就是這樣的,這只是第一步,,在后面經(jīng)過每一個非最終目的端設(shè)備的時候,,都要將目的 MAC 地址設(shè)置為下一跳設(shè)備的 MAC 地址,因為以太網(wǎng)幀就是這樣設(shè)計的,。所以說,,在整個傳輸過程中,以太網(wǎng)幀會不斷的解析然后重新封裝,,目的就是把下一跳的 MAC地址封裝進去,。直到最終到達了目的設(shè)備所在的網(wǎng)絡(luò)。 目的MAC 地址是一跳一跳變化的,,但是 IP 頭中的目的 IP 地址是絕對不能變的,,要不然就真的找不到了。 路由器A如何路由的當數(shù)據(jù)包到達路由器A之后,,就要走出子網(wǎng)A,,奔向更廣闊的網(wǎng)絡(luò)世界了,。還是結(jié)合上面的圖來看,這個拓撲結(jié)構(gòu)還是很簡單的,,真實情況下,,可能要經(jīng)過十幾二十個路由設(shè)備。 數(shù)據(jù)包來到路由器之后,,路由器要怎么處理呢,,路由器會進行路由操作,也就是將這個包安排一條最合適的路徑發(fā)出去,。 這就要提到路由表了,。 路由器中維護著一張路由表,主要存放網(wǎng)絡(luò),、主機與下一跳的對應(yīng)關(guān)系,。例如下表這樣:
大致的意思就是如果收到一個數(shù)據(jù)報,在當前路由器的路由表中尋找,,一般目標都是一個網(wǎng)絡(luò)地址(標明一個子網(wǎng)),,把具體數(shù)據(jù)包的IP地址和當前路由表的子網(wǎng)掩碼進行與操作,如果得到的結(jié)果和路由表目標欄一直,,就轉(zhuǎn)發(fā)給這條記錄中的下一跳地址,,從網(wǎng)絡(luò)接口欄所記錄的接口發(fā)出(也就是路由器上的網(wǎng)口或者叫端口)。 如果下一跳地址是0.0.0.0 ,,表示這個目的IP地址就在當前網(wǎng)絡(luò)中,。那就不用路由器轉(zhuǎn)發(fā)了,,拿到目的IP的MAC地址,,就可以直接發(fā)送了(獲取MAC地址的方法,前面說過了,,先查ARP表,,沒有的話,再用ARP廣播請求獲?。?。 如果下一跳不是0.0.0.0,表示目的IP不是本網(wǎng)絡(luò)的地址,,就發(fā)給下一跳的地址,。 如果在路由表中都沒有找到匹配的目標網(wǎng)絡(luò),那就看有沒有配置默認條目了,,默認條目也就是目標是0.0.0.0的條目,,表示任意的IP都可以通過此條目的下一跳(也就是默認網(wǎng)關(guān))地址轉(zhuǎn)發(fā)出去。 如果在路由表中沒有找到任何匹配的目標網(wǎng)絡(luò),,并且沒有設(shè)置默認條目,,那就直接將數(shù)據(jù)包丟棄,,并返回一個 主機不可達的 ICMP 請求。 路由表分為靜態(tài)路由和動態(tài)路由,,靜態(tài)就是需要人手工配置,,路由表是固定不變的,動態(tài)路由是根據(jù)一些規(guī)則動態(tài)更新路由表數(shù)據(jù),,總之,, 路由表最終會有一些描述網(wǎng)絡(luò)拓撲結(jié)構(gòu)的記錄存在。 當路由器A收到數(shù)據(jù)包之后,,解封裝這個數(shù)據(jù)包,,從下層網(wǎng)上拆,鏈路層拆出 MAC 地址,,發(fā)現(xiàn)就是自己的,,繼續(xù)拆,拆到 IP 層,,找到目的 IP 地址,,拆到 IP 層就可以了。然后拿著這個目表 IP 地址在路右邊中檢索,,看看是否正好有對應(yīng)的目標網(wǎng)絡(luò),。 拿192.168.8.0(子網(wǎng)掩碼是255.255.255.0)這個目標網(wǎng)絡(luò)來說,目標是一個網(wǎng)絡(luò)地址,,可以理解為一個子網(wǎng)(局域網(wǎng)),,那如果IP數(shù)據(jù)報里的目標IP是192.168.8.8/24或192.168.8.188/24都能對應(yīng)上這一條記錄,因為這兩個地址和子網(wǎng)掩碼與操作之后,,得出的網(wǎng)絡(luò)地址都是192.168.8.0,。于是就發(fā)給下一跳 0.0.0.0。 假設(shè)我們的目標IP是114.21.1.1,,通過查表發(fā)現(xiàn)了正好有目標地址是114.21.1.0的記錄,,于是轉(zhuǎn)發(fā)給下一跳地址 114.21.1.100,通過en0這個接口發(fā)出去,,直接發(fā)送到了與之相連的子網(wǎng)B的頂層交換機,。 如果沒有找到對應(yīng)的記錄,查看是否有默認路由,,也就是目的地址是0.0.0.0的記錄,,如果有的話,就發(fā)給默認路由對應(yīng)的下一跳地址,。如果連默認路由也沒有,,直接將包丟棄,然后回復(fù)給源IP 一個類型為主機不可達的ICMP包,。告訴源主機,,此路不通了,,然后應(yīng)用程序根據(jù)這個信息,選擇新的應(yīng)對策略,。 子網(wǎng)B的交換機X轉(zhuǎn)發(fā)包數(shù)據(jù)包從路由器A出來之后先到了子網(wǎng)B的頂層交換機,,然后經(jīng)過頂層交互機的轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)給了子網(wǎng)B的交換機X,。頂層交換機如何轉(zhuǎn)發(fā)就不說了,,和交換機X的轉(zhuǎn)發(fā)過程是一致的。 交換機的轉(zhuǎn)發(fā)就要說到轉(zhuǎn)發(fā)表了,。 在交換機中維護著一張叫做轉(zhuǎn)發(fā)表的映射表,。一臺交換機上有很多個接口,每個接口連接一臺設(shè)備,。轉(zhuǎn)發(fā)表記錄的就是接口和所連接的設(shè)備的MAC地址的映射關(guān)系,。交換機就是根據(jù)這張表將數(shù)據(jù)幀傳輸?shù)街付ǖ闹鳈C端口上的。 數(shù)據(jù)包走到交換機這里了,,說明它離目的地已經(jīng)不遠了,,已經(jīng)找到目標主機所在的局域網(wǎng)內(nèi)了。 當數(shù)據(jù)包到達交互機后,,交換機檢查自己的MAC表是否有數(shù)據(jù)幀中目的MAC地址的匹配條目,,如果有,則會根據(jù)MAC表中記錄的對應(yīng)端口將數(shù)據(jù)幀轉(zhuǎn)發(fā)出去,,這一轉(zhuǎn)發(fā)方式稱為「單播」,。 而如果沒有,則會將該數(shù)據(jù)幀從非來源端口的其它全部端口發(fā)送出去,,這一轉(zhuǎn)發(fā)方式程序稱為「廣播」,。。 假設(shè)交換機 X 收到數(shù)據(jù)包后,,根據(jù)目標MAC地址查詢轉(zhuǎn)發(fā)表,,沒查到,,這時候,,交換機X就將包從端口1和端口2廣播出去給主機X-1和主機X-2,主機X-1收到這個包后,,對比目的MAC地址和自己的是否一致,,結(jié)果發(fā)現(xiàn)這個包是發(fā)給自己的,會回復(fù)交換機X一個數(shù)據(jù)包,,包含自己的(主機X-1)的MAC地址,,這時,交換機X就將這個MAC地址和交換機上對應(yīng)的端口的映射關(guān)系記錄到轉(zhuǎn)發(fā)表,。這一過程通常稱為「自學(xué)習(xí)」,。 主機X-2發(fā)現(xiàn)包不是發(fā)給自己的,,直接就忽略了。 到此為止,,主機X-1就順利收到包了,,確切的說是一個以太網(wǎng)幀。 子網(wǎng)B的主機X-1收到包之后主機X-1收到這個數(shù)據(jù)幀之后,,鏈路層解析,,發(fā)現(xiàn)正好是發(fā)給自己的,因為目標MAC地址和自己的一致,,然后交給網(wǎng)絡(luò)層,,發(fā)現(xiàn)目的IP也是自己的,于是交給傳輸層,,傳輸層解析TCP段,,最后將數(shù)據(jù)交給上層的應(yīng)用層,應(yīng)用層根據(jù)TCP的目的端口號,,判斷是那個應(yīng)用程序要處理收到的數(shù)據(jù),。 總結(jié)下面的流程圖是對上述過程的匯總,可以點開下面的大圖查看,。 其中有幾個細節(jié)要理解,,對理解整個過程有很大幫助。 1,、鏈路層的以太網(wǎng)數(shù)據(jù)幀必須要有目的端的 MAC 地址,,而且必須是下一跳的 MAC 地址。別問為什么,,協(xié)議就是這么規(guī)定的,。 2、正因為鏈路層以太網(wǎng)幀必須是下一跳MAC地址,,所以整個傳輸過程中,,以太網(wǎng)幀是一直解包、重組的,,目的就是把下一跳MAC地址重組進去,。 3、網(wǎng)絡(luò)層 IP 協(xié)議中的目的 IP地址是不能變的,,那有人要問了,,發(fā)送端和目的端雖然不是在一個子網(wǎng)中,但它們的局域網(wǎng)地址都是 192.168.1 網(wǎng)段的,,那怎么能找到目的主機呢,。本篇并沒有討論這個問題,這其實就要牽扯到公網(wǎng)和內(nèi)網(wǎng)的映射了,,一個局域網(wǎng)最終會映射到一個公網(wǎng) IP 地址上,,比如路由器可以設(shè)置 NAT 功能,。 4、ARP 協(xié)議只工作在局域網(wǎng)中,,ARP 通過 IP 獲取 MAC 地址,,是通過向局域網(wǎng)內(nèi)所有主機廣播 ARP 請求的,只有對應(yīng)的 IP 地址才會回復(fù)這個 ARP 請求,。 5,、每經(jīng)過一個路由設(shè)備,都要將 IP 數(shù)據(jù)報拆包,,然后再重組,,源IP地址設(shè)置為自己的,然后 TTL 減一,,TTL 有一個限制,,比如 32,當路由次數(shù)超過這個數(shù)值,,表示網(wǎng)絡(luò)環(huán)境不是很好,,繞的太遠了,就會把這個包丟棄掉,。 |
|