一個數據包的互聯網漫游記
英文原文:Journey of a Data Packet in the Internet
盡管大多數最終用戶都不關心 Internet 是如何工作的,但是我相信你們當中的仍然會有一些人對 Internet 運轉的基本原理非常感興趣。
在這篇文章中,我們會通過闡釋一個數據包從源到目的地的征程,來試著撥開互聯網的第一層神秘面紗。由此出發,我們會盡量讓本文的內容保持簡單基礎。
在更進一步之前,讓我們先快速簡要地理解一下 DHCP 和 DNS 的概念。
DHCP
你有沒有想過你的計算機是如何獲取 IP 地址的?嗯……首先你必須知道計算機獲取 IP 地址是有兩種途徑的,一種是靜態方式,另一種是動態方式。
靜態方式就是由管理員在機器上手動設置 IP 地址。如果你的計算機連接在局域網或者類似的網絡上的話,需要注意的是你所設置的 IP 地址不能和網絡上任何其他機器的 IP 地址相同,因為那樣會引起 IP 地址沖突,兩臺機器就都不能連接到 Internet 了。
動態方式就是計算機(在系統啟動的時候)請求一臺服務器來為它分配一個 IP 地址。這一過程使用的協議稱為動態主機配置協議(DHCP)。這里提到的服務器就是 DHCP 服務器,這臺服務器負責為網絡上所有的計算機分配 IP 地址。此時由 DHCP 來保證沒有 IP 地址沖突。如果一臺機器關閉繼而重啟,那么一條刷新 DHCP 的請求就發送到 DHCP 服務器上,這一次可能會分配給它一臺與原來相同或者不同的 IP 地址。通常 DHCP 服務器會得到一個 IP 地址池,DHCP 服務器只能分配該地址池內的地址。這么做是為了保證將其他 IP 地址作為靜態地址的時候不會引起任何沖突。
DNS
我們大多數人都使用過 google.com 進行搜索,不過你有沒有想過為什么在瀏覽器里面輸入 google.com 就能連接到 Google 的服務器呢?嗯……要理解這件事情,我們需要理解域名服務器(DNS)的概念。
就如同現實生活中人們通過名字互相區分一樣,在計算機網絡的世界里,不同的計算機之間通過指派給它們的 IP 地址來互相區分。IP 地址有兩種類型:公有和私有。通常服務器使用公有地址,這是因為他們要被全世界數以百萬計的計算機訪問。至于你那連接在路由器上的個人電腦,它通常獲取到 的是私有 IP。由于公有地址的數量是有限的,所以現在搭設局域網(在一個有著公有 IP 的路由下搭建)然后使用私有地址開始變得流行并且非常成功。
記憶 IP 地址這樣的任務對于大多數人來說有些困難,于是每個服務器都還有一個名字(比如 google.com)。這樣最終用戶只需要記住這個名字,在瀏覽器中輸入它,然后敲回車就可以了。現在讓我來看看當用戶在瀏覽器中輸入名字并敲回車之后 究竟發生了什么。首先,需要把域名轉換成對應的 IP。要完成這項任務,需要給默認網關(大多數情況下就是路由器)發送一條與 DNS 請求。路由都會配置一個 DNS 服務器地址,這個地址便是 DNS 請求的目的地。
DNS 服務器用來將域名轉換成 IP 地址。當 DNS 服務器收到一條請求后,它會檢查它有沒有該請求需要的轉換信息。如果沒有這條轉換信息,那么 DNS 服務器會把這條請求轉發給其他的 DNS 服務器。通過這種方式,就完成了從域名到 IP 地址的轉換。轉換結果隨后會發回到發出請求的計算機。
DNS 之后又發生了些些什么?
要理解下面的解釋,你應該對 TCP/IP 協議族有一定的了解。當然啦,我們會盡量保持解釋的簡單性。
- 一旦通過 DNS 得到了目標 IP 地址,應用層就會準備好一條 HTTP GET 請求。隨后這條請求會前進到傳輸層。
- 這一層有兩個主要的協議——TCP 和 UDP。正是在這一層,該請求被封裝為了傳輸層數據包。如果用的是 TCP 協議,還要保證包的大小不能超過源和目的地之間 MTU(最大傳輸單元)的最小值。這樣做的目的是避免數據包在傳輸過程中分片(fragmentation)。另一方面,如果用的 UDP 的話,就不用顧慮這么多了,當然了這種情況下,包就有可能分片了。
- 一旦傳輸層的包封好了,接著它就會被推到 IP 層。這一層會增加源和目的地的 IP 地址以及一些其他有用的信息,諸如 TTL(time to live 生存期)、分段信息等等。所有的這些信息在數據包抵達目的地的路途中都是有用的。
- 當數據包進入到數據鏈路層之后,與 MAC 地址相關的信息就會加諸其上,隨后數據包就會被推送到物理層。這樣一串“0”和“1”就會從你的網卡里發送到物理媒介中去。
如果數據包的目的地沒有直接連接在源計算機上,那么根據源計算機上存儲的路由信息,數據包就會傳送到最近的網絡節點上去。網絡中有各種不同的節點,比如路由、網橋、網關等等。每一種都有重要的作用,例如路由用來傳送 IP 包,網橋用來連接不同協議的異構網絡。
如果我們考慮一個簡單的網絡的話,路由就是將數據包從源送到目的地的最主要的角色。數據包離開源計算機后,與其相連的路由(數據要先發送到這里)的 MAC 地址就這個包的目的 MAC 地址。
數據包到達該路由之后,路由就會做下面幾件事情:
- 減記 TTL 值,重新計算數據包的校驗和。
- 搜索其路由表,以檢查其中有沒有數據包的目的 IP 所對應的主機。如果有的,路由就將該包發到相應的主機。
- 如果沒有這樣的一條路由,就從路由表中搜索源于該目的 IP 的網絡的地址。如果有的話就將該包發送到這個特定的網絡。
- 如果上面的兩次搜索都失敗的話,該數據包就被發送到路由表中指定的默認路由。
上面的所有情況中,不論數據包是在路由之間傳送還是從路由傳送到目的地,目的 MAC 地址都會變成最近的路由或者目的地的 MAC 地址。通過這種方式,目的 IP 地址保持不變,而目的 MAC 地址不斷從一個路由變為另一個。就是這樣,數據包從一臺路由到下一臺路由,直到它抵達終點。
啊哈,千難萬險之后我們的 HTTP GET 請求終于到達目的地啦:
- 數據包首先抵達物理層,該層向 CPU 發送一個 IRQ 來告訴 CPU 有數據到了,需要處理。
- 當數據被送到數據鏈路層后,就會檢查它的 MAC 地址來確認該數據包確實發到這臺計算機的。
- 如果上述檢查通過的話,數據包就會傳到 IP 層。在這里會檢查數據包的 IP 地址以及其校驗和,隨后將其傳送到相應的傳輸層。
- 這些都完成了之后,該信息(在我們的例子里是 HTTP GET 請求)就會根據端口的值被送到監聽該端口的應用中去。
- 我們的請求就是這樣送抵 Google 的網絡服務器的。
之后,相應的響應會以與上述相同的方式傳送回來。
現在你都了解了,這就是數據包在 Internet 上從源到目的地的旅程。