在前兩篇文章中,我們完整的描述了計算機網路 OSI 五層模型的相關內容。那麼,本篇將會從一個實踐案例開始,帶你從整體上重新認識我們的計算機網路。
我們以訪問 Google 為例,當我們在瀏覽器位址列中敲下Enter鍵之後,整個計算機網路將會發生什麼呢?
本機的網路相關引數如下:
首先我們應用層的瀏覽器決定向 DNS 伺服器請求解析域名「www.google.com」,那麼就要遵循 DNS 協議。
DNS 執行在 53 號埠,於是瀏覽器會建立一個 UDP 套接字,標識該套接字的二元組分別是『目的 IP 地址』和『目的埠』。而套接字本質上就是為了唯一標識應用層程式,就是為了讓響應報文能夠找到目的地。
那麼這裡會建立一個 UDP 套接字,二元組為「本機 IP 地址 192.168.43.138」和「隨機產生一個未使用的埠號」。
接著,瀏覽器將 DNS 請求報文封裝好推入套接字,開始我們的 DNS 解析過程。
有關 DNS 的相關細節,這裡不再贅述了,可以參考前面的文章,拿到 DNS 伺服器的響應報文,運輸層拆開資料包,得到該報文的目的 IP 地址和目的埠號,於是對應著去找套接字交付報文即可。
最終我們會從『本地 DNS 伺服器』得到 Google 的 IP 地址為:172.194.72.105。
整個 HTTP 請求可以說才剛剛開始:
應用層
瀏覽器封裝 HTTP 請求報文,然後建立一個 TCP 套接字,採用四元組標識,具體為「源 IP 地址:192.168.43.138」+「源埠號:隨機的,這裡假設為 1234」+「目的 IP 地址:172.194.72.105」+「目的埠號:80」。
HTTP 報文也就是我們的應用層資料包,大致是這樣的:
指定了一些請求引數與動作,以及一些要求響應報文的返回格式要求,具體的我們不細說了。
緊接著,這個報文會被推進 TCP 套接字中,等待運輸層來收取。
運輸層
運輸層收取了報文,並判斷與目的主機是否建立了 TCP 連線,這裡假設沒有。
那麼,運輸層將不急著傳送應用層資料,得先判斷與目的主機之間能夠正常通訊,也就是需要『握手』打招呼。
『三次握手』的相關細節,我們這裡也不再贅述了,上篇文章描述的很詳細了,通過『三次握手』,傳送端和接收端確認過傳送與確認序號,分配了相應的快取資源等。
一切準備就緒之後,運輸層將應用層發過來的資料包又一層封裝,新增進『源埠號』和『目的埠號』以及相關差錯檢驗欄位。
最後將 TCP 資料包向下傳遞到網路層。
網路層
網路層其實很簡單,拿到資料包並封裝成 IP 資料包,即在原 TCP 報文的前提之上新增『源 IP 地址』和『目的 IP 地址』等欄位資訊。
然後交由資料鏈路層。
鏈路層
資料鏈路層拿到 IP 資料包,它需要封裝成乙太網幀才能在網路中傳輸,也就是它需要目的主機的 Mac 地址,然而我們只知道目的主機的 IP 地址。
所以,鏈路層有一個 ARP 協議,直接或間接的能夠根據目的 IP 地址獲得使用該 IP 地址的主機 Mac 地址。
當然,ARP 協議執行的前提是,目的 IP 地址和當前傳送方主機處於同一子網路中。如果不然,傳送方將目的 Mac 地址填自己閘道器路由的 Mac 地址,然後通過物理層傳送出去。
閘道器路由由於具有轉發表和路由選擇演算法,所以它知道目的網路該怎麼到達,所以一路轉發,最終會傳送到目的網路的閘道器路由上。
最後,目的網路的閘道器路由同樣會經由 ARP 協議,取得目的主機的 Mac 地址,然後廣播傳送,最後被目的主機接受。
這樣谷歌的伺服器就接受到一個 HTTP 請求,於是它解析這個請求,確定該請求的動作是什麼,也就是它需要什麼東西,並構建響應報文,以同樣的方式從網路到達源主機。
最後你將看到你想要的谷歌搜尋頁面:
整體上我們自頂而下的描述了一個請求到達目的地的完整過程,旨在巨集觀上建立完整的框架體系,相關細節之處可以參照前兩篇文章。
文章中的所有程式碼、圖片、檔案都雲端儲存在我的 GitHub 上:
(https://github.com/SingleYam/overview_java)
歡迎關注微信公眾號:撲在程式碼上的高爾基,所有文章都將同步在公眾號上。