TCP/IP--圖解從URL到網頁通訊原理

Jacky心外無事發表於2018-06-08

前言

網際網路的原始目的,就是為了傳輸文字(文字對話)。那我們使用瀏覽器傳送請求後頁面是如何呈現在我們面前的呢? 接下來由圖片介紹下URL到呈現頁面的過程。

一、文字對話--從請求到響應

客戶端(瀏覽器)請求過程.jpg
我們在瀏覽器中輸入一個 URL,回車之後便會在瀏覽器中觀察到頁面內容。實際上這個過程是:

(1)瀏覽器向網站所在的伺服器傳送了一個 Request(請求)

(2)網站伺服器接收到這個Request之後進行處理和解析

(3)然後返回對應的一個Response(響應)給瀏覽器,Response裡面就包含了頁面的原始碼等內容

(4)瀏覽器再對其進行解析便將網頁呈現了出來。

這個文字對話的過程是建立在怎樣的規則上面呢?簡單說,這個通訊的過程是基於TCP/IP通訊協議族規範上實現的,完成從客戶端到伺服器端等一系列資訊交換的流程。

二、TCP/IP 協議族介紹

1、TCP/IP協議族是什麼呢?

TCP/IP協議族的目的就是通過建立規則使計算機之間可以進行資訊交換。

相互通訊的雙方就必須基於相同的方法,比如由哪一邊先發起通訊、使用哪種語言進行通訊、怎樣結束通訊等規則都需要事先確定,我們就把這種規則稱為協議(protocol)。通常我們說的TCP/IP協議族是網際網路相關的各類協議族的總稱。

TCP/IP協議族
TCP/IP協議族由那麼多的協議組成,那功能上如何劃分的呢?

這裡就說到TCP/IP重要的層次化劃分,按層次可以分為4層:應用層、傳輸層、網路層和鏈路層。(層次化的好處在於每個層次內部的設計可以自由改動,並通過各層的介面關聯起來,而如果只有一個協議統籌就需要對所有涉及到的部分都重新設計。)

應用層、傳輸層、網路層和鏈路層

2、TCP/IP各功能層的作用

(1) 應用層:決定了向使用者提供應用服務時候的通訊活動。應用層負責傳送各種最終形態的資料,是直接與使用者打交道的層,典型協議是HTTP、FTP等。

(2) 傳輸層:負責傳送文字資料。傳輸層有兩個性質不同的協議: TCP(Transmission Control Protocol,傳輸控制協議)和 UDP(User Data Protocol,使用者資料包協議)。

TCP UDP

(3) 網路層:負責分配地址和傳送二進位制資料,主要協議是IP協議;

(4) 鏈路層:負責建立電路連線,是整個網路的物理基礎,典型的協議包括乙太網、ADSL等。

3、TCP/IP 通訊傳輸流

在TCP/IP各功能層之間資料是如何流動傳輸的呢?

通訊傳輸流

(1)首先作為傳送端的客戶端在應用層(HTTP 協議)發出的 HTTP請求(如:想瀏覽www.baidu.com),並生成HTTP報文。

(2)為了傳輸方便,在傳輸層(TCP 協議)把從應用層處收到的資料(HTTP 請求報文)進行分割,並在 各個報文上打上標記序號及埠號後轉發給網路層。

(3)在網路層(IP 協議),增加作為通訊目的地的 MAC 地址後轉發給鏈路層。

(4)給這些資料附加上乙太網首部並進行傳送處理,生成的乙太網資料包將通過物理層傳輸給接收端。

(5)接收端的伺服器在鏈路層接收到資料,按序往上層傳送,一直到應用層。當傳輸到應用層,才能算真正接收到由客戶端傳送過來的 HTTP 請求。

在通訊過程每經過一層時必定會被打上一個該層所屬的首部資訊。反之,接收端在層與層傳輸資料時,每經過一層時會把對應的首部消去。

三、基於TCP/IP通訊過程

一張圖來說明請求到網頁呈現的通訊過程( 下圖基於IP 協議、TCP 協議 、DNS 服務和HTTP 協議的通訊過程),並對每一步做說明:

通訊過程.png

1、瀏覽器輸入URL傳送請求

URL(Uniform Resource Locator,統一資源定位符),是使用 Web 瀏覽器等訪問 Web 頁面時需要輸入的網頁地址。

url

URL由以下元素組成:

URL格式介紹.png
(1) 傳送協議:http:或者https:等

(2) 層級URL標記符號:為“//”固定不變

(3) 登入資訊: 訪問資源需要的憑證資訊(可省略)

(4) 伺服器地址:通常為域名,有時為IP地址(實際通訊中需要通過IP地址訪問,域名通過DNS伺服器解析出IP地址)

(5) 埠號:以數字方式表示,若為HTTP的預設值“:80”可省略

(6) 路徑:以“/”字元區別路徑中的每一個目錄名稱

(7) 查詢:GET模式的窗體引數,以“?”字元為起點,每個引數以“&”隔開,再以“=”分開引數名稱與資料,通常以UTF8的URL編碼,避開字元衝突的問題

(8) 片段:以“#”字元為起點,使用片段識別符號通常可標記出已獲取資源中的子資源

2、DNS對請求中的URL域名解析

DNS協議.png
DNS(Domain Name System)服務是和 HTTP協議一樣位於應用層的協議,它提供域名到 IP 地址之間的解析服務。

計算機既可以被賦予IP地址,也可以被賦予主機名和域名,使用者通常使用主機名或域名來訪問對方的計算機,而不是直接通過 IP 地址訪問。而計算機相對更容易處理一組數字,這時DNS域名解析服務應運而生。DNS 協議提供通過域名查詢 IP 地址(或逆向從 IP 地址反查域名的服務)。

3、HTTP協議生成請求報文

HTTP協議:HyperText Transfer Protocol超文字傳輸協議位於應用層,決定從客戶端到伺服器端等一系列通訊內容及方式,這通過生成報文併傳送完成通訊。

HTTP協議
(1)請求報文的構成

請求報文
(2)響應報文的構成

響應報文

4、TCP協議提供可靠的位元組流傳輸服務

TCP協議:Transmission Control Protocol傳輸控制協議,位於傳輸層。

(1)位元組流服務(Byte Stream Service)是指,為了方便傳輸,將大塊資料分割成以報文段(segment) 為單位的資料包進行管理。

(2)可靠的傳輸服務是指,能夠把資料準確可靠地傳給對方。TCP 協議採用了三次握手連線等策略保證傳輸的可靠性(三次握手,四次揮手文末會有重點補充)

3次握手.png

5、IP協議實現資料傳遞到對方計算機

IP(Internet Protocol)網際協議位於網路層。 IP協議的作用在於實現資料包傳遞到對方計算機IP地址。而IP間的通訊依賴於MAC 地址(網路卡所屬的固定地址),還需要再通過ARP 協議根據通訊方的 IP 地址反查出對應的MAC 地址。

IP協議.png

6、接收並解析請求報文後回傳響應報文

伺服器接收及解析請求報文後回傳響應報文.png
接收端(伺服器)響應報文同樣利用TCP/IP通訊協議回傳

四、TCP建立連線及斷開(重點補充)

TCP建立連線(3次握手)

TCP 提供面向有連線的通訊傳輸,面向有連線是指在資料通訊開始之前先做好兩端之間的準備工作。 三次握手是指建立一個TCP連線時需要客戶端和伺服器端總共傳送三個標記包以確認連線的建立。下面來看看三次握手的流程圖:

3次握手

第一次握手:客戶端將標誌位SYN置為1,隨機產生一個值seq=J,並將該資料包傳送給伺服器端,客戶端進入SYN_SENT狀態,等待伺服器端確認。

第二次握手:伺服器端收到資料包後由標誌位SYN=1知道客戶端請求建立連線,伺服器端將標誌位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,並將該資料包傳送給客戶端以確認連線請求,伺服器端進入SYN_RCVD狀態。

第三次握手:客戶端收到確認後,檢查ack是否為J+1,ACK是否為1,如果正確則將標誌位ACK置為1,ack=K+1,並將該資料包傳送給伺服器端,伺服器端檢查ack是否為K+1,ACK是否為1,如果正確則連線建立成功,客戶端和伺服器端進入ESTABLISHED狀態,完成三次握手建立連線,隨後客戶端與伺服器端之間可以開始傳輸資料了。

為什麼3次握手: 前兩次的握手很顯然是必須的,主要是最後一次,即客戶端收到服務端發來的確認後為什麼還要想服務端再傳送一次確認呢?這主要是為了防止已失效的請求報文段突然又傳送到了服務端而產生連線的誤判。

考慮如下的情況: 客戶端傳送了一個連線請求報文段到服務端,但是在某些網路節點上長時間滯留了,所以客戶端又超時重發了一個連線請求報文段該服務端,而後正常建立連線,資料傳輸完畢,並釋放了連線。 如果這時候第一次傳送的請求報文段(已過期的)延遲了一段時間後,又到了服務端,很顯然,這本是一個早已失效的報文段,但是服務端收到後會誤以為客戶端又發出了一次連線請求,於是向客戶端發出確認報文段,並同意建立連線。假設不採用三次握手,這時服務端只要傳送了確認,新的連線就建立了。但由於客戶端現階段沒有發出建立連線的請求,因此不會理會服務端的確認,也不會向服務端傳送資料,而服務端卻認為新的連線已經建立了,並在一直等待客戶端傳送資料,這樣服務端就會一直等待下去,直到超出保活計數器的設定值,而將客戶端判定為出了問題,才會關閉這個連線。這樣就浪費了很多伺服器的資源。而如果採用三次握手,客戶端沒有再向服務端發出確認,服務端由於收不到確認,就知道客戶端沒有要求建立連線,從而不建立該連線。

TCP斷開連線(4次揮手)

TCP連線是全雙工的,因此,每個方向都必須要單獨進行關閉, 四次揮手即終止TCP連線,就是指斷開一個TCP連線時,需要客戶端和服務端總共傳送4個包以確認連線的斷開。 下面來看看四次揮手的流程圖:

4次揮手

注:中斷連線端可以是客戶端,也可以是伺服器端。下文舉的例子是以客戶端發出中斷請求。

第一次揮手:客戶端傳送一個FIN=M,用來關閉客戶端到伺服器端的資料傳送,客戶端進入FIN_WAIT_1狀態。意思是說"我客戶端沒有資料要發給你了",但是如果你伺服器端還有資料沒有傳送完成,則不必急著關閉連線,可以繼續傳送資料。

第二次揮手:伺服器端收到FIN後,先傳送ack=M+1,告訴客戶端,“你的請求我收到了,但是我還沒準備好,請繼續你等我的訊息。”這個時候客戶端就進入FIN_WAIT_2狀態,繼續等待伺服器端的FIN報文。

第三次揮手:當伺服器端確定資料已傳送完成,則向客戶端傳送FIN=N報文,告訴客戶端,好了,我這邊資料發完了,準備好關閉連線了。伺服器端進入LAST_ACK狀態。

第四次揮手:客戶端收到FIN=N報文後,就知道可以關閉連線了,但是他還是不相信網路,怕伺服器端不知道要關閉,所以傳送ACK=1,ack=N+1後進入TIME_WAIT狀態,如果伺服器端沒有收到ACK則可以重傳。伺服器端收到ACK後,就知道可以斷開連線了(CLOSED狀態)。客戶端等待了2MSL(時間MSL叫做最長報文壽命,RFC建議設為2分鐘)後依然沒有收到回覆,則證明伺服器端已正常關閉,客戶端也可以關閉連線了。最終完成了四次握手。

為什麼4次揮手:TCP協議是一種面向連線的、可靠的位元組流的運輸層通訊協議,TCP是全雙工模式,這就意味著,當客戶端發出FIN報文段時,只是表示客戶端已經沒有資料要傳送了,客戶端告訴伺服器,它的資料已經全部傳送完畢了;但是,這個時候客戶端還是可以接受來自伺服器的資料;當伺服器返回ACK報文段時,表示它已經知道客戶端沒有資料傳送了,但是主機2還是可以傳送資料到客戶端的;當伺服器也傳送了FIN報文段時,這個時候就表示伺服器也沒有資料要傳送了,就會告訴客戶端,我也沒有資料要傳送了,之後彼此就會愉快的中斷這次TCP連線。

為什麼客戶端TIME_WAIT等待2MSL: (1)為了保證客戶端傳送的最後一個ACK報文段能夠到達伺服器。該ACK報文段很有可能丟失,因而使處於在LIST—ACK狀態的伺服器收不到對已傳送的FIN+ACK報文段的確認,伺服器可能會重傳這個FIN+ACK報文段,而客戶端就在這2MSL時間內收到這個重傳的FIN+ACK報文段,接著客戶端重傳一次確認,重新啟動2MSL計時器,最後客戶端和伺服器都進入CLOSED狀態。(2)防止已失效的請求連線出現在本連線中。在連線處於2MSL等待時,任何遲到的報文段將被丟棄,因為處於2MSL等待的,由該插口(插口是IP和埠對的意思,socket)定義的連線在這段時間內將不能被再用,這樣就可以使下一個新的連線中不會出現這種舊的連線之前延遲的報文段。

小結

以上,我們瞭解TCP/IP協議的作用及通訊的流程,針對Http協議後續再做詳細介紹。


參考文獻:

《圖解http》(下載地址)

《一篇文章帶你熟悉 TCP/IP 協議(網路協議篇二)》

阮一峰《tcp-ip模型》

《【網路協議】TCP連線的建立和釋放》

相關文章