什麼是URL
URL
是統一資源定位符(Uniform Resource Locator),是資源標識最常見的形式。URL
描述了一臺特定伺服器上某資源的特定位置。它們可以明確說明如何從一個精確、固定的位置獲取資源。
URL
說明了協議、伺服器和本地資源。
而瀏覽器都是基於HTTP
協議,而HTTP
是個應用層的協議。HTTP
無需操心網路通訊的具體細節都交給了TCP/IP
。TCP
:
- 無差錯的資料傳輸。
- 按序傳輸(資料總是按照傳送的順序到達)。
- 未分段的資料流(可以在任意時刻將資料傳送出去)。
HTTP協議位於TCP的上層。HTTP使用TCP來傳輸其報文資料。
解析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 查詢的過程如下圖所示。
-
在瀏覽器中輸入
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
協議收到報文段時,對其中所攜帶的各種控制資訊 ( SYN
、FIN
、ACK
、URG
和RST
標誌,還可能有資料和選項 )的處理順序不是隨意的,也不是各種實現可以自行決定的。
從 CLOSED
狀態到SYN_SENT
狀態的變遷就標明傳送了一個SYN
報文段。在圖中則沒有采用這種標記方法,而是在每個狀態框中標出處於該狀態時要傳送的報文段型別。例如,當處於SYN_RECV
狀態時,要發出一個帶有 SYN
的報文段,其中還包括對所收到SYN
的確認( ACK
)。而當處於CLOSE_WAIT
狀態時,要發出對所收到FIN
的確認( ACK
)。
我們之所以要這樣做是因為,在TCP
協議中我們經常需要處理可能造成多次狀態變遷的報文段。於是在處理一個報文段時,重要的是處理完報文段後連線所處的最終狀態,因為它決定了應答的內容。而如果不使用TCP
協議,每收到一個報文段通常至多隻引起一次狀態變遷,只有在收到SYN/ACK
報文段時才是例外。
三次握手
客戶端和伺服器之間建立連線需要經過三次確認的階段,我們稱之為TCP
的三次握手。
第一次
客戶端傳送一個
syn
報文,設定傳送序號為X
,客戶端進入SYN_SENT
狀態,等待伺服器回應。
第二次
服務端收到
syn
報文,但是服務端必須確定客戶端的syn(ack= X + 1)
, 因此服務端也要傳送一個syn=Y
給客戶端進行確認,表示服務端已經收到客戶端的請求。
服務端需要傳送ack+syn
給客戶端,此時伺服器進入SYN_RECV
狀態。
第三次
客戶端收到伺服器的syn+ack
包,向伺服器傳送確認包ack(ack=Y+1)
,此包傳送完畢,客戶端和伺服器進入ESTABLISHED
(TCP
連線成功)狀態,完成三次握手。
舉個例子
比如你走在路上,發現前面有你的朋友向你走過來,你向你朋友揮手(第一次握手)。
你朋友看見了你向他打招呼,但是你朋友因為距離你太遠,並不確定是否是跟他打招呼的,因此,你朋友用手指了下自己,並向你示意(第二次握手)。
你看見了你朋友的表情和動作,你需要給你朋友一個肯定,此時,你點頭示意(第三次握手)。
此時你和你朋友互相聊天(TCP已連線
)。
四次揮手
由於TCP
連線是全雙工的,因此每個方向都必須單獨進行關閉。
這原則是當一方完成它的資料傳送任務後就能傳送一個FIN
來終止這個方向的連線。收到一個 FIN
只意味著這一方向上沒有資料流動,一個TCP
連線在收到一個FIN
後仍能傳送資料。
首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
TCP
客戶端傳送一個FIN
,用來關閉客戶到伺服器的資料傳送。- 伺服器收到這個
FIN
,它發回一個ACK
,確認序號為收到的序號加1。和SYN
一樣,一個FIN
將佔用一個序號。 - 伺服器關閉客戶端的連線,傳送一個
FIN
給客戶端。 - 客戶端發回
ACK
報文確認,並將確認序號設定為收到序號加1。
揮手例子
你和你朋友聊天,聊著聊著,突然想起來女朋友鑰匙丟了,你是回家開門的,現在耽誤了半小時了,嚇得冷汗都出來了,一想起榴蓮。。。
這個時候,你趕緊跟你朋友說了情況,你說你馬上得回去了,下次再聊(第一次揮手)。
你朋友聽了,覺得也是得趕緊回去,就跟你說你趕緊回去吧。(第二次揮手)。
然後,你朋友走了,並向你揮手道別(第三次揮手)。
你看見你朋友跟你道別,你同樣也跟你朋友道別(第四次揮手)。
回去之後,你就需要玩玩你的榴蓮了。
頁面渲染
檢視下篇文章瀏覽器渲染原理(效能優化之如何減少重排和重繪)
最後
參考文章:
1、HTTP
權威指南。
3、TCP-IP
詳解卷