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