從URL到頁面顯示
1.解析 URL
浏覽器第一步要做的就是解析
URL
,進而生成發送給
Web
伺服器的請求資訊。
URL 元素組成
http: + // Web伺服器 + [/ + 目錄名 + / ... + 檔案名]
對
URL
進行解析之後,浏覽器确定了 Web 伺服器和檔案名,接下來就是對這些資訊生成 HTTP 請求。
2. DNS 解析域名
浏覽器解析 URL 并生成 HTTP 消息後,需要委托作業系統将消息發送給 Web 伺服器。
但是委托作業系統發送消息時,必須提供通信對象的 IP 位址。
而使用者輸入的伺服器域名,如
www.baidu.com
, 并不是真正意義上的位址。網際網路上每一台計算機的唯一辨別是他的 IP 位址,那麼我們就需要通過
DNS 解析域名
,通過伺服器域名獲得其真實的 IP 位址。
例如,我們可以使用
ping
指令來擷取
www.baidu.com
的真實 IP 位址

可以看到
39.156.66.14
才是其伺服器的 IP 位址,那麼我們就可以直接通過這個位址通路其首頁
那麼我們的計算機又是如何進行域名到IP位址的轉換呢?
有一種伺服器專門儲存了
Web 伺服器域名
與
IP 位址
的對應關系,它就是
DNS 伺服器
。
域名層級關系
DNS 中的域名都是用
.
來進行分割的,比如
www.baidu.com
,這裡的
.
代表了不同層次之間的界限。
在域名中,從左到右,層級遞增。
域名的層級結構類似樹狀結構:
- 根 DNS 伺服器 (
).
- 頂級域 DNS 伺服器 (
.com.
- 權威 DNS 伺服器 (
.baidu.com.
這裡并不是多打了一個
.
,這個
.
對應的就是根域名伺服器,預設情況所有網址的最後一位都是
.
, 則為了友善使用者通常都會省略。
域名解析
上圖就是查找
www.baidu.com
的 IP 位址過程。
- 用戶端發出 DNS 請求,發送給本地域名伺服器,查詢 www.baidu.com 的 IP 位址
- 本地域名伺服器收到用戶端請求後,如果緩存中能夠找到 www.baidu.com 的 IP 位址,則它直接傳回給用戶端
- 若沒有在緩存中找到則會詢問根域名伺服器
的位址。.com
- 根域名伺服器不直接解析域名位址,而是儲存了頂級域名伺服器的位址。 根域名服務收到本地域名伺服器的請求後,會傳回
頂級域名伺服器的 IP 位址。.com
- 本地域名伺服器收到
的 IP 位址後,向頂級域名伺服器送出請求。.com
- 頂級域名伺服器收到請求後,傳回權威域名伺服器
的 IP 位址.baidu.com
- 本地域名伺服器收到權威域名伺服器位址後,向權威域名伺服器送出請求。
- 權威域名伺服器查詢對應的 IP 位址
傳回給本地域名伺服器39.156.66.14
- 本地域名伺服器收到 IP 位址後,會将其儲存到高速緩存中
- 本地域名伺服器将 IP 位址傳回給用戶端。
利用
dig +trace xxx.xxx.xxx
指令,我們可看到
DNS 解析
的過程。
3. TCP 連接配接
HTTP 協定是使用 TCP 作為傳輸協定的。
TCP 格式
我們首先來看看 TCP 封包頭的格式
- 端口号:TCP 位于運輸層,運輸層提供了程序間的邏輯通信。故需要源端口号和目标端口号,将資料轉發給特定的應用。
- 序号:用于對位元組流進行編号。在網絡中,封包段并不一定是按照發送順序達到目的地的,是以需要序号來解決亂序的問題。例如序号為 201,表示第一個位元組的編号為 201,如果攜帶的資料長度為 100 位元組,那麼下一個封包段的序号應為 301。
- 确認号:期望收到下一個封包段的序号。例如 B 正确收到 A 發送來的一個封包段,序号為 501,攜帶的資料長度為 200 位元組,是以 B 期望下一個封包段的序号為 701,B 發送給 A 的确認封包段中确認号就為 701。
- 資料偏移:指的是資料部分距離封包段起始處的偏移量,實際指的首部長度。(TCP 首部的長度并不是固定的)
- 确認 ACK:當 ACK=1 時,确認号字段有效,否則無效。TCP 規定,在連接配接建立後所有傳送的封包段都必須把 ACK 置為 1
- 同步 SYN:在連接配接建立時用來同步序号。當 SYN=1,ACK=0時表示這是一個連接配接請求封包段,若對方同意建立連接配接,則響應封包中SYN=1,ACK=1。
- 終止 FIN:用來釋放一個連接配接,當 FIN=1 時,表示此封包段的發送方資料已發送完畢,并要求釋放連接配接。
- 視窗:TCP要做流量控制,通信雙方各申明一個視窗大小,辨別自己目前的處理能力。
三次握手
- 開始時,用戶端和服務端都處于
狀态。伺服器打開後監聽某一端口,處于CLOSED
狀态LISTEN
- 然後用戶端主動發起連接配接請求封包,SYN=1,ACK=0, 選擇一個初始序号 x,之後處于
SYN-SENT
- 服務端收到發起的連接配接,如果同意建立連接配接,則向用戶端發送連接配接确認封包,SYN=1,ACK=1,确認号為 x+1,同時也選擇一個初始序号 y,之後處于
SYN-RCVD
- 用戶端收到服務端連接配接确認封包後,還要向服務端發出确認,ACK = 1,确認号為 y+1,序号為 x+1,之後處于
ESTABLISHED
- 服務端收到用戶端的确認後,連接配接建立,之後處于
ESTABLISHED
TCP連接配接為什麼要進行三次握手?
目的:保證雙方都有發送和接收的能力
發送方 | 接收方 | ||
---|---|---|---|
第一次握手 | 用戶端 | 服務端 | 服務端确認用戶端具有發送能力 |
第二次握手 | 用戶端可以确認服務端具有接收和發送能力 | ||
第三次握手 | 服務端确認用戶端具有接收能力 |
4. IP
TCP 在執行連接配接、收發、斷開等各階段操作時,都需要委托 IP 将資料封裝成網絡包發送給通信對象。
IP 資料報格式
- 版本:有4(IPv4)和6(IPv6)兩個值
- 首部長度:占 4 位,是以最大值為 15。值為 1 表示的是 1 個 32 位字的長度,也就是 4 位元組。因為固定部分長度為 20 位元組,是以該值最小為 5。如果可選字段的長度不是 4 位元組的整數倍,就用尾部的填充部分來填充。
- 區分服務:用來獲得更好的服務,一般情況下不使用。
- 總長度:首部長度和資料部分長度
- 辨別 : 在資料報長度過長進而發生分片的情況下,相同資料報的不同分片具有相同的辨別符。
- 片偏移 : 和辨別符一起,用于發生分片的情況。片偏移的機關為 8 位元組。
- 生存時間:TTL,它的存在是為了防止無法傳遞的資料報在網絡中不斷兜圈子。以路由器跳數為機關,當 TTL 為 0 時就丢棄資料報
- 協定:指出攜帶的資料應該上交給哪個協定進行處理,例如 ICMP、TCP、UDP 等。
- 首部檢驗和 :因為資料報每經過一個路由器,都要重新計算檢驗和,是以檢驗和不包含資料部分可以減少計算的工作量。
- 源位址、目的位址:發送方和接收方的 IP 位址
路由表轉發
我們可以使用
route -n
指令檢視目前系統的路由表
根據上面的路由表,我們假設 Web 伺服器的目的位址為
172.16.205.200
- 假設先和第三個條目的子網路遮罩(
) 進行與運算,得到結果為Genmask
,但是第三個條目的172.16.0.0
是Destination
,兩者不一緻是以比對失敗172.17.0.0
- 再與第二個條目的子網路遮罩進行與運算,得到結果為
, 與第二個條目的172.16.205.0
比對,是以将使用Destionation
網卡的 IP 位址進行轉發ens33
第一個條目比較特殊,它的目标位址和子網路遮罩都是
0.0.0.0
,這表示預設網關,如果其他所有條目都無法比對,就會自動比對這一行。
Gateway
即路由器的 IP 位址。
位址解析協定 ARP
網絡層實作主機與主機之間的通信,而鍊路層實作具體每段鍊路之間的通信。在通信過程中,IP 資料報的源位址和目的位址始終不變,而 MAC 位址随着鍊路的改變而改變。
路由器的端口具有 MAC 位址,是以它就能夠作為以太網的發送方和接收方,同時還具有 IP 位址。
當轉發包時,首先路由器端口會接收發給自己的以太網包,然後路由表查詢轉發目标,再由相應的端口作為發送将以太網包發送出去。
每個主機都有一個 ARP 高速緩存,裡面有本區域網路上的各主機和路由器的 IP 位址到 MAC 位址的映射表。
當緩存中不存在所需 IP 位址的 MAC 位址時,就需要 ARP 協定 進行廣播
下一個路由器會将包轉發給再下一個路由器,經過層層轉發之後,網絡包就到達了最終目的地。
5. 伺服器與用戶端
資料包抵達伺服器後,伺服器會先扒開資料包的 MAC 頭部,檢視是否和伺服器自己的 MAC 位址符合,符合就将包收起來。
接着繼續扒開資料包的 IP 頭,發現 IP 位址符合,根據 IP 頭中協定項,知道自己上層是 TCP 協定。
于是,扒開 TCP 的頭,裡面有序列号,需要看一看這個序列包是不是我想要的,如果是就放入緩存中然後傳回一個 ACK,如果不是就丢棄。TCP頭部裡面還有端口号, HTTP 的伺服器正在監聽這個端口号。
于是,伺服器自然就知道是 HTTP 程序想要這個包,于是就将包發給 HTTP 程序。
伺服器的 HTTP 程序看到,原來這個請求是要通路一個頁面,于是就把這個網頁封裝在 HTTP 響應封包裡。
HTTP 響應封包也需要穿上 TCP、IP、MAC 頭部,不過這次是源位址是伺服器 IP 位址,目的位址是用戶端 IP 位址。
穿好頭部衣服後,從網卡出去,交由交換機轉發到出城的路由器,路由器就把響應資料包發到了下一個路由器,就這樣跳啊跳。
最後跳到了用戶端的城門把手的路由器,路由器扒開 IP 頭部發現是要找城内的人,于是把包發給了城内的交換機,再由交換機轉發到用戶端。
用戶端收到了伺服器的響應資料包後,同樣也非常的高興,客戶能拆快遞了!
于是,用戶端開始扒皮,把收到的資料包的皮扒剩 HTTP 響應封包後,交給浏覽器去渲染頁面,一份特别的資料包快遞,就這樣顯示出來了!
最後,用戶端要離開了,向伺服器發起了 TCP 四次揮手,至此雙方的連接配接就斷開了。