經典面試題:在瀏覽器地址欄輸入一個 URL 後回車,背後發生了什麼

{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"🎓 盡人事,聽天命。博主東南大學研究生在讀,熱愛健身和籃球,正在爲兩年後的秋招準備中,樂於分享技術相關的所見所得,關注公衆號 @ ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"飛天小牛肉","attrs":{}},{"type":"text","text":",第一時間獲取文章更新,成長的路上我們一起進步","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"🎁 本文已收錄於 ","attrs":{}},{"type":"link","attrs":{"href":"https://gitee.com/veal98/CS-Wiki","title":null},"content":[{"type":"text","text":"CS-Wiki(Gitee 官方推薦項目,現已 0.9k star)","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":",致力打造完善的後端知識體系,在技術的路上少走彎路,歡迎各位小夥伴前來交流學習","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"0. 前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在瀏覽器的地址欄輸入一個 URL 後回車,背後到底發生了什麼才能使得一個界面完美的展現在我們眼前?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"今天講解的這道題目,由於其涉及大量網絡協議,可以非常直觀的看出諸位小夥伴對計算機網絡體系的整體把握程度,所以自然成爲了各大公司的面試常客。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在瀏覽中輸入 URL 並且獲取響應的過程,其實就是瀏覽器和該 URL 對應的服務器的網絡通信過程。比如我們輸入 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"www.baidu.com","attrs":{}}],"attrs":{}},{"type":"text","text":",那麼會返回一個百度搜索的界面,這其實就是瀏覽器和百度服務器之間的網絡通信過程。瀏覽器就是客戶端,用於發出請求,而百度的服務器就是服務端,用於接收並響應請求。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面我們就來詳細講解這個龐大的網絡通信過程。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1. 解析 URL","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不知道有沒有同學會混淆域名和 URL 的概念,可以這樣理解,URL 就是我們輸入的網址,而網址裏面含有域名。舉個例子:","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"www.baidu.com/veal98","attrs":{}}],"attrs":{}},{"type":"text","text":" 是一個網址,而 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"www.baidu.com","attrs":{}}],"attrs":{}},{"type":"text","text":" 就是服務器的域名。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"URL 各元素的組成如下(當然,下述請求文件的路徑名可以省略):","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d7/d7e918bd20dfa1a80ed8f974eae9677d.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個 URL 請求的目標服務器上的文件路徑就是:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9a/9a384ada423976f6856f7c95ca37d5b9.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼首先,瀏覽器做的第一步就是解析 URL 得到裏面的參數,將域名和需要請求的資源分離開來,從而瞭解需要請求的是哪個服務器,請求的是服務器上什麼資源等等。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2. 瀏覽器封裝 HTTP 請求報文","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"URL","attrs":{}}],"attrs":{}},{"type":"text","text":" 進行解析之後,瀏覽器確定了目標服務器和文件名,接下來就需要根據這些消息","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"封裝","attrs":{}},{"type":"text","text":"成一個 HTTP 請求報文發送出去。舉個 HTTP 請求報文的例子:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關於 HTTP 協議詳細可見 ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/98FtlAy0mAtf6tGplQMDqA","title":null},"content":[{"type":"text","text":"HTTP 協議的前世今生","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":" 這篇文章,這裏不再贅述","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b1/b1f41e3a73078f72483d7e2e30a59109.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解釋一下","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"封裝","attrs":{}},{"type":"text","text":",這是一個貫穿整個計算機網絡的概念。就是說","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}}],"text":"發送端在層與層之間傳輸數據時,每經過一層必定會被打上一個該層所屬的首部信息。反之,接收端在層與層之間傳輸數據時,每經過一層就會把該層對應的首部信息消去","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/59/59e259a65d2b45e5d2f9840b955db32a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3. DNS 域名解析獲取 IP 地址","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"封裝好 HTTP 請求報文後,在正式還有一項準備工作沒有做,那就是獲取目標服務器的 IP 地址。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然解析得到了域名,理論瀏覽器已經知道目標服務器是誰了。但是實際上,域名並不是目標服務器真正意義上的地址,互聯網上每一臺計算機都被全世界唯一 IP 地址標識着,但是 IP 地址並不方便記憶,所以才設計出了域名。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼就需要解析域名獲取目標服務器的 IP 地址。不然空有一個方便記憶的域名咋知道這個請求到底發送到哪裏去呢。由域名轉換得到 IP 地址就是 DNS 協議做的事情,如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關於 DNS 詳細的內容各位可以回顧 ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/AfVqL7lEsbRE-YLOPZ4gDQ","title":null},"content":[{"type":"text","text":"超詳細 DNS 協議解析","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":" 這篇文章,比如什麼是域名,域名服務器,遞歸查詢和迭代查詢等等,寫的已經足夠詳細,此處只列出 DNS 的解析過程。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1)首先搜索","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"瀏覽器的 DNS 緩存","attrs":{}},{"type":"text","text":",緩存中維護着一張域名與 IP 地址的對應表;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2)若沒有命中,則繼續搜索","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"操作系統的 DNS 緩存","attrs":{}},{"type":"text","text":";","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3)若仍然沒有命中,則操作系統將域名發送至","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"本地域名服務器","attrs":{}},{"type":"text","text":",本地域名服務器查詢自己的 DNS 緩存,查找成功則返回結果(注意:主機和本地域名服務器之間的查詢方式是","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"遞歸查詢","attrs":{}},{"type":"text","text":");","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4)若本地域名服務器的 DNS 緩存沒有命中,則本地域名服務器向上級域名服務器進行查詢,通過以下方式進行","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"迭代查詢","attrs":{}},{"type":"text","text":"(注意:本地域名服務器和其他域名服務器之間的查詢方式是迭代查詢,防止根域名服務器壓力過大):","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先本地域名服務器向","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"根域名服務器","attrs":{}},{"type":"text","text":"發起請求,根域名服務器是最高層次的,它並不會直接指明這個域名對應的 IP 地址,而是返回頂級域名服務器的地址,也就是說給本地域名服務器指明一條道路,讓他去這裏尋找答案","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本地域名服務器拿到這個","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"頂級域名服務器","attrs":{}},{"type":"text","text":"的地址後,就向其發起請求,獲取","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"權限域名服務器","attrs":{}},{"type":"text","text":"的地址","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本地域名服務器根據權限域名服務器的地址向其發起請求,最終得到該域名對應的 IP 地址","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4)本地域名服務器將得到的 IP 地址返回給操作系統,同時自己將 IP 地址緩存起來","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"5)操作系統將 IP 地址返回給瀏覽器,同時自己也將 IP 地址緩存起來","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"6)至此,瀏覽器就得到了域名對應的 IP 地址,並將 IP 地址緩存起來","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"配合下圖直觀理解:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9f/9f6405d37759bdf7e8845cf8cef6fcb7.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要注意的是,DNS 使用的是 UDP 協議,也就是說上面各種請求的轉發,都是基於 UDP 這個無連接協議的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"4. 建立 TCP 連接","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獲取到了目標服務器的 IP 地址之後,瀏覽器就知道我等下請求要發給誰了,這個時候就可以開始發送封裝好了的 HTTP 請求報文了,那麼既然需要發送請求,必然就需要 TCP 通過三次握手爲瀏覽器和服務器之間建立可靠的連接,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"保證雙方都具有可靠的接收和發送能力","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏又是一道經典的面試題:TCP 三次握手和四次揮手,詳細可見 ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/u56NcMs68sgi6uDpzJ61yw","title":null},"content":[{"type":"text","text":"關於 TCP 三次握手和四次揮手,滿分回答在此","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":" 這篇文章。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"三次握手過程如下圖:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5e/5eeaa9858321baf7da2c67647e24fc31.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"5. 瀏覽器發送請求","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"TCP 三次握手完成後,瀏覽器與目標服務器之間就建立了一個可靠的虛擬通道,於是瀏覽器就可以發送自己的 HTTP 請求了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要注意的是,HTTP 請求報文或者響應報文在 TCP 連接通道上進行傳輸的時候,由於這些報文比較大,爲了更容易和準確可靠的傳輸,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"TCP 會將 HTTP 報文按序號分割成若干報文段並加上 TCP 首部,分別進行傳輸。接收方在收到這些報文段後,按照序號以原來的順序重組 HTTP 報文","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"6. 負責傳輸的 IP 協議","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"實際上,TCP 在三次握手建立連接、四次握手斷開連接、以及連接建立過程中的收發數據(TCP 報文段)等各階段操作時,都是通過 IP 協議進行傳輸的,IP 協議將這些階段的數據添加 IP 首部封裝成 IP 數據報再進行傳輸。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"IP 數據報的首部存有","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"源 IP 地址","attrs":{}},{"type":"text","text":"和 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"目標 IP 地址","attrs":{}},{"type":"text","text":"。所謂源 IP 地址 就是發送方的 IP 地址;目標 IP 地址就是通過 DNS 域名解析得到的目標服務器的 IP 地址。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"事實上,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"IP 協議身處的網絡層規定的是:數據報要通過怎樣的路徑(傳輸路線)才能到達對方計算機,並傳送給對方","attrs":{}},{"type":"text","text":"。不理解這句話的詳細解釋馬上就來,繼續往下讀。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"7. 使用 ARP 協議憑藉 MAC 地址通信","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關於 IP 協議、IP 地址、MAC 地址等詳細請看 ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/NO9RDt1A3T1rz-Q4_Y0gPw","title":null},"content":[{"type":"text","text":"別再恐懼 IP 協議(萬字長文 | 多圖預警)","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":" 這篇文章。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面說了,IP 協議的作用是把各種數據包傳送給對方,而要保證確實傳送到對方那裏,則需要滿足各類條件,其中必要的兩個就是 IP 地址 和 MAC 地址。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"MAC 地址也是用來唯一標識一個接入互聯網的設備的,可能不禁有小夥伴要問,既然網絡層已經有了唯一標識的 IP 地址,爲啥還需要 MAC 地址?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"看下面這幅圖,在網絡上,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"通信的雙方在同一局域網內的情況是很少見的,通常是需要多臺計算機和網絡設備的中轉才能連接到對方。而在進行中轉時,就需要利用下一站中轉設備的 MAC 地址來搜索下一個中轉目標","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ed/ed2cfcdb04276aa2133b7abc3363d098.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"網絡層指定了從哪個主機(「源 IP 地址」)發送到哪個主機(「目的 IP 地址」)。","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"源 IP 地址和目標 IP 地址在傳輸過程中是不會變化的","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而數據鏈路層則是根據 MAC 地址在一個接一個的區間中進行傳輸的,每個區間內的出發地址即「源 MAC 地址」,每個區間內的目的地址即「目的 MAC 地址」。顯然,隨着數據的傳輸,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"源 MAC 地址和目的 MAC 地址會不斷的發生變化","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"🍉 這麼說吧,舉個形象點的例子:我們把數據鏈路層當成乘坐高鐵從蘇州到南京,再在南京轉乘到北京,再在北京轉乘到西藏的旅客,那麼網絡層就相當於每個車站的工作人員,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"在數據鏈路層每次轉乘時,網絡層爲其購買了一張標有下一個 MAC 地址的車票","attrs":{}},{"type":"text","text":"。因此,即使旅客(數據鏈路層)不知道其最終目的地也沒有關係,工作人員(網絡層)會給你做出指引。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"實際上,網絡層做出指引的過程,我們將其稱爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"路由控制","attrs":{}},{"type":"text","text":",其中又涉及到了路由協議比如 OSPF 等","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/de/de4f87597acb6e217eba4d85fdd2e2fc.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"將 IP 地址轉化爲 MAC 地址","attrs":{}},{"type":"text","text":",從而在數據鏈路層精確的傳輸數據的協議就是 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ARP 協議","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ARP 是藉助 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ARP 請求與 ARP 響應","attrs":{}},{"type":"text","text":"兩種類型的包確定 MAC 地址的。並且每個主機都有一個 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ARP 高速緩存","attrs":{}},{"type":"text","text":",裏面有本局域網上的各主機和路由器的 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"IP 地址到 MAC 地址的映射表","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如下圖所示,假定主機 A 向同一鏈路上的主機 B 發送 IP 數據報,已知主機 A 和主機 B 的 IP 地址,它們互不知道對方的 MAC 地址:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e1/e12c96ec0489f7faa1cac2b688935c53.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1)首先,主機 A 爲了獲得主機 B 的 MAC 地址,它會先去查詢自己的 ARP 高速緩存中有沒有主機 B 的相關記錄;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2)如果主機 A 的 ARP 高速緩存中沒有主機 B 的 IP 地址到 MAC 地址的映射,主機 A 就會通過","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"廣播","attrs":{}},{"type":"text","text":"的方式發送 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ARP 請求包","attrs":{}},{"type":"text","text":"(該包攜帶自己的 IP 地址 和 MAC 地址 以及 目標主機的 IP 地址),表明自己想要獲得主機 B 的 MAC 地址;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2) 由於廣播請求可以被同一個鏈路上的所有主機或路由器接收,因此如果這條鏈路上某個主機或路由的 IP 地址與這個 ARP 請求包中包含的目標主機的 IP 地址相同,那麼這個節點就將自己的 MAC 地址塞入 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ARP 響應包","attrs":{}},{"type":"text","text":"中返回給主機 A;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f5/f53a7e4467e4dfcc1bc83afa78d5ff02.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當然,ARP 響應包是以單播的形式進行發送的,畢竟 ARP 請求包中已經包含了主機 A 的 IP 地址,所以主機 B 非常清楚這個響應包應該發送給誰。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大部分網絡協議在設計的時候,都是保持極度剋制的,不需要的交互就砍掉,能合併的信息就合併,能不用廣播就用單播,以此讓帶寬變得更多讓網絡變得更快。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3)主機 A 在收到主機 B 發過來的 ARP 響應包後,向其 ARP 高速緩存中寫入主機 B 的 IP 地址到 MAC 地址的映射。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e5/e5653fb861691cb6d74d5164cbe39c3c.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當然,緩存是有一定期限的,超過這個期限,緩存的內容將被清空。這也使得即使 MAC 地址和 IP 地址的映射關係發生了變化,也依然能夠正確的將數據包發送給目標地址。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"8. 服務器響應請求","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"瀏覽器的 HTTP 請求報文通過 TCP 三次握手建立的連接通道被切分成若干報文段分別發送給服務器,服務器在收到這些報文段後,按照序號以原來的順序重組 HTTP 請求報文。然後處理並返回一個 HTTP 響應。當然,HTTP 響應報文也要經過和 HTTP 請求報文一樣的過程。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"看下方這個圖回顧一下(圖片來源《圖解 HTTP》):","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/82/826515bf33a83d1e8e222382f5c63517.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"9. 斷開 TCP 連接","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"瀏覽器和服務器都不再需要發送數據後,四次揮手斷開 TCP 連接,詳細可見 ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/u56NcMs68sgi6uDpzJ61yw","title":null},"content":[{"type":"text","text":"關於 TCP 三次握手和四次揮手,滿分回答在此","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":" 這篇文章。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"10. 瀏覽器顯示界面","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"瀏覽器接收到服務器返回的數據包,根據瀏覽器的渲染機制對相應的數據進行渲染","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"屏蔽掉底層細節,籠統的總結一下上述過程:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"應用層:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"瀏覽器封裝 HTTP 請求報文","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"DNS 解析域名獲得目標服務器地址","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"傳輸層:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"建立連接","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"把應用層傳過來的 HTTP 請求報文進行分割,並在各個報文上打上標記序號及端口號轉發給網絡層","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"網絡層:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"利用 ARP 協議根據 IP 地址獲取作爲通信目的地的 MAC 地址後轉發給鏈路層","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務端在鏈路層收到數據,按序往上層發送,一直到應用層接收到瀏覽器發送來的 HTTP 請求報文,然後處理該請求並返回 HTTP 響應報文,瀏覽器接收到響應報文之後解析渲染界面。最後 TCP 斷開連接。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"🎉 關注公衆號 | 飛天小牛肉,即時獲取更新","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"博主東南大學研究生在讀,利用課餘時間運營一個","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"公衆號『 飛天小牛肉 』","attrs":{}},{"type":"text","text":",2020/12/29 日第一次開通,專注分享計算機基礎(數據結構 + 算法 + 計算機網絡 + 數據庫 + 操作系統 + Linux)、Java 基礎和麪試指南的相關原創技術好文。本公衆號的目的就是","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"讓大家可以快速掌握重點知識,有的放矢","attrs":{}},{"type":"text","text":"。希望大家多多支持哦,和小牛肉一起成長 😃","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"並推薦個人維護的開源教程類項目: ","attrs":{}},{"type":"link","attrs":{"href":"https://gitee.com/veal98/CS-Wiki","title":null},"content":[{"type":"text","text":"CS-Wiki(Gitee 推薦項目,現已 0.9k star)","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":", 致力打造完善的後端知識體系,在技術的路上少走彎路,歡迎各位小夥伴前來交流學習 ~ 😊","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章