瀏覽器位址列裡輸入URL後的全過程

光光同學發表於2019-01-09

什麼是URL

URL統一資源定位符(Uniform Resource Locator),是資源標識最常見的形式。URL描述了一臺特定伺服器上某資源的特定位置。它們可以明確說明如何從一個精確、固定的位置獲取資源。

URL說明了協議、伺服器和本地資源。

而瀏覽器都是基於HTTP協議,而HTTP是個應用層的協議。HTTP無需操心網路通訊的具體細節都交給了TCP/IP
TCP:

  • 無差錯的資料傳輸。
  • 按序傳輸(資料總是按照傳送的順序到達)。
  • 未分段的資料流(可以在任意時刻將資料傳送出去)。

HTTP協議位於TCP的上層。HTTP使用TCP來傳輸其報文資料。

HTTP

解析URL

當使用者輸入一個完整的URL之後,瀏覽器就開始解析URL的構成,以便於查詢資源地址,大多數URL的語法通用格式如下:

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
複製程式碼

基本上沒有哪個URL包含了所有這些元件。URL最重要的3個部分是方案scheme,主機host和路徑path
如果URL中不包含port,瀏覽器會預設使用80埠進行訪問。

DNS域名解析

什麼是DNS?

DNS( Domain Name System)是“域名系統”的英文縮寫,DNS是應用層協議,事實上他是為其他應用層協議工作的,包括不限於HTTP和SMTP以及FTP,用於將使用者提供的主機名解析為ip地址。

DNS 查詢的過程如下圖所示。

瀏覽器位址列裡輸入URL後的全過程

  • 在瀏覽器中輸入www.qq.com 域名,作業系統會先檢查自己本地的hosts檔案是否有這個網址對映關係,如果有,就先呼叫這個IP地址對映,完成域名解析。

  • 如果hosts裡沒有這個域名的對映,則查詢本地DNS解析器快取,是否有這個網址對映關係,如果有,直接返回,完成域名解析。

  • 如果hosts與本地DNS解析器快取都沒有相應的網址對映關係,首先會找TCP/ip引數中設定的首選DNS伺服器,在此我們叫它本地DNS伺服器,此伺服器收到查詢時,如果要查詢的域名,包含在本地配置區域資源中,則返回解析結果給客戶機,完成域名解析,此解析具有權威性。

  • 如果要查詢的域名,不由本地DNS伺服器區域解析,但該伺服器已快取了此網址對映關係,則呼叫這個IP地址對映,完成域名解析,此解析不具有權威性。

  • 如果本地DNS伺服器本地區域檔案與快取解析都失效,則根據本地DNS伺服器的設定(是否設定轉發器)進行查詢,如果未用轉發模式,本地DNS就把請求發至13臺根DNS,根DNS伺服器收到請求後會判斷這個域名(.com)是誰來授權管理,並會返回一個負責該頂級域名伺服器的一個IP。本地DNS伺服器收到IP資訊後,將會聯絡負責.com域的這臺伺服器。這臺負責.com域的伺服器收到請求後,如果自己無法解析,它就會找一個管理.com域的下一級DNS伺服器地址(http://qq.com)給本地DNS伺服器。當本地DNS伺服器收到這個地址後,就會找http://qq.com域伺服器,重複上面的動作,進行查詢,直至找到www.qq.com主機。

  • 如果用的是轉發模式,此DNS伺服器就會把請求轉發至上一級DNS伺服器,由上一級伺服器進行解析,上一級伺服器如果不能解析,或找根DNS或把轉請求轉至上上級,以此迴圈。不管是本地DNS伺服器用是是轉發,還是根提示,最後都是把結果返回給本地DNS伺服器,由此DNS伺服器再返回給客戶機。

從客戶端到本地DNS伺服器是屬於遞迴查詢,而DNS伺服器之間就是的互動查詢就是迭代查詢。

建立TCP連線

TCP根據不同的當前狀態(常規或加星)所傳送的內容:

常規狀態 說 明 發 送 加 星 狀 態 發 送
CLOSED 關閉 RST, ACK
LISTEN 監聽連線請求(被動開啟)
SYN_SENT 已發出SYN (主動開啟) SYN SYN_SENT* SYN, FIN
SYN_RCVD 已經發出和收到SYN;等待ACK SYN, ACK SYN_RCVD* SYN, FIN, ACK
ESTABLISHED 連線已經建立(資料傳輸) ACK ESTABLISHED* SYN, ACK
CLOSE_WAIT 收到FIN,等待應用程式關閉 ACK CLOSE_WAIT* SYN, FIN
FIN_WAIT_1 已經關閉,發出FIN;等待ACK和FIN FIN, ACK FIN_WAIT_1 SYN, FIN, ACK
CLOSING 兩端同時關閉;等待ACK FIN, ACK CLOSING* SYN, FIN, ACK
LAST_ACK 收到FIN已經關閉;等待ACK FIN, ACK LAST_ACK* SYN, FIN, ACK
FIN_WAIT_2 已經關閉;等待FIN ACK
TIME_WAIT 主動關閉後長達2 M S L的等待狀態 ACK

TCP中定義了7個擴充套件狀態,這些擴充套件狀態都稱為加星狀態。它們分別是:SYN_SENT*SYN_RCVD*ESTABLISHED *CLOSE_WAIT *LAST_ACK *FIN_WAIT_1 *CLOSING *

TCP輸入的處理順序

TCP協議收到報文段時,對其中所攜帶的各種控制資訊 ( SYNFINACKURGRST 標誌,還可能有資料和選項 )的處理順序不是隨意的,也不是各種實現可以自行決定的。

瀏覽器位址列裡輸入URL後的全過程

CLOSED狀態到SYN_SENT狀態的變遷就標明傳送了一個SYN報文段。在圖中則沒有采用這種標記方法,而是在每個狀態框中標出處於該狀態時要傳送的報文段型別。例如,當處於SYN_RECV狀態時,要發出一個帶有 SYN 的報文段,其中還包括對所收到SYN的確認( ACK )。而當處於CLOSE_WAIT狀態時,要發出 對所收到FIN的確認( ACK )。

我們之所以要這樣做是因為,在TCP協議中我們經常需要處理可能造成多次狀態變遷的 報文段。於是在處理一個報文段時,重要的是處理完報文段後連線所處的最終狀態,因為它決定了應答的內容。而如果不使用TCP協議,每收到一個報文段通常至多隻引起一次狀態 變遷,只有在收到SYN/ACK報文段時才是例外。

三次握手

瀏覽器位址列裡輸入URL後的全過程

客戶端和伺服器之間建立連線需要經過三次確認的階段,我們稱之為TCP的三次握手。

第一次

客戶端傳送一個syn報文,設定傳送序號為X,客戶端進入SYN_SENT狀態,等待伺服器回應。

第二次

服務端收到syn報文,但是服務端必須確定客戶端的syn(ack= X + 1), 因此服務端也要傳送一個syn=Y給客戶端進行確認,表示服務端已經收到客戶端的請求。
服務端需要傳送ack+syn給客戶端,此時伺服器進入SYN_RECV狀態。

第三次

客戶端收到伺服器的syn+ack包,向伺服器傳送確認包ack(ack=Y+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHEDTCP連線成功)狀態,完成三次握手。

舉個例子

比如你走在路上,發現前面有你的朋友向你走過來,你向你朋友揮手(第一次握手)。

你朋友看見了你向他打招呼,但是你朋友因為距離你太遠,並不確定是否是跟他打招呼的,因此,你朋友用手指了下自己,並向你示意(第二次握手)。

你看見了你朋友的表情和動作,你需要給你朋友一個肯定,此時,你點頭示意(第三次握手)。

此時你和你朋友互相聊天(TCP已連線)。

四次揮手

瀏覽器位址列裡輸入URL後的全過程

由於TCP連線是全雙工的,因此每個方向都必須單獨進行關閉。

這原則是當一方完成它的資料傳送任務後就能傳送一個FIN來終止這個方向的連線。收到一個 FIN只意味著這一方向上沒有資料流動,一個TCP連線在收到一個FIN後仍能傳送資料。

首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

  • TCP客戶端傳送一個FIN,用來關閉客戶到伺服器的資料傳送。
  • 伺服器收到這個FIN,它發回一個ACK,確認序號為收到的序號加1。和SYN一樣,一個FIN將佔用一個序號。
  • 伺服器關閉客戶端的連線,傳送一個FIN給客戶端。
  • 客戶端發回ACK報文確認,並將確認序號設定為收到序號加1。

揮手例子

你和你朋友聊天,聊著聊著,突然想起來女朋友鑰匙丟了,你是回家開門的,現在耽誤了半小時了,嚇得冷汗都出來了,一想起榴蓮。。。

這個時候,你趕緊跟你朋友說了情況,你說你馬上得回去了,下次再聊(第一次揮手)。

你朋友聽了,覺得也是得趕緊回去,就跟你說你趕緊回去吧。(第二次揮手)。

然後,你朋友走了,並向你揮手道別(第三次揮手)。

你看見你朋友跟你道別,你同樣也跟你朋友道別(第四次揮手)。

回去之後,你就需要玩玩你的榴蓮了。

頁面渲染

檢視下篇文章 瀏覽器渲染原理(效能優化之如何減少重排和重繪)

最後

參考文章:

1、HTTP權威指南。

2、DNS原理及其解析過程【精彩剖析】

3、TCP-IP詳解卷

相關文章