HTTP-點開瀏覽器輸入網址背後發生的那點事
前言
Internet最早來源於美國國防部ARPANet,1969年投入運行,到現在已有很長一段路了,各位想要了解發展史可以百度下,這裏就不多說了。
現如今當我們想要獲取一些資料,首先是打開某個瀏覽器,在地址欄輸入地址,想要的信息出現在你的面前。
大家有沒有想過輸入地址就能返回給你想要的信息是怎麽實現的呢?
下面就來簡單說下它的實現流程,不過在這之前先來了解下HTTP基本概念如下
HTTP基本概念
在這引用http://www.zsythink.net/archives/76
這是一篇為初學者準備的文章,所以作者會盡量從基礎出發,盡量細致的描述每一個細節,以求讓初學者不會一頭霧水,有一定基礎的同學就不用看了,以免浪費你的時間。
假設博主今天春心蕩漾,想要訪問一些不可描述的小網站,於是,博主悄悄的打開了瀏覽器,在瀏覽器的地址欄中輸入了一個小網站的網址,
此處假設這個小網站的網址為 www.zsythink.net ,當博主輸入了這個網址以後,瀏覽器中就顯示了博主想要看到的內容,整個過程如下圖所示。
那麽,瀏覽器返回給我們的內容是怎麽產生的呢?
這些內容肯定不是憑空產生的,而是有人為我們準備了這些內容,當我們在瀏覽器的地址欄中輸入網址以後,
這些提前準備好的內容即可返回到瀏覽器中,以便有需要的人能夠查看到這些內容,
而查看這些內容的人就是我們平常所說的"客戶",客戶往往會通過"客戶端程序"去請求、查看這些內容,
我們最常使用的客戶端程序就是瀏覽器了,所以,在之後的http相關的文章中,
如果沒有特別說明,我們所說的"客戶端"就是指"瀏覽器",我們使用客戶端去查看我們想要的內容,
而提供內容的一端被稱為"服務端",當作為客戶時,我們需要在電腦上安裝客戶端軟件(即瀏覽器),
通過客戶端軟件查看我們想要的內容,而作為提供內容的人,也需要在服務端的計算機上安裝對應的軟件,
才能為我們提供服務,而服務端的計算機就是我們常說的"服務器",安裝在服務器上的、為我們提供內容的軟件被稱之為"web服務器軟件"。
所以,綜上所述,我們可以了解到如下名詞
註:如下名詞的解釋均針對http而言,在後面的文章中我們會解釋什麽是http,此處不用糾結
客戶端:客戶端通常是指瀏覽器,比如谷歌瀏覽器、火狐瀏覽器、IE等,瀏覽器安裝在客戶使用的電腦上,所以,在描述http時,客戶端通常也代指那些安裝了瀏覽器的電腦。
服務端:服務端通常是指那些安裝了"web服務軟件"的計算機,這些服務端的計算機被稱為服務器。
沒錯,聰明如你一定想到了,說白了,客戶端與服務端就是兩臺電腦,分別安裝了不同的軟件,服務端提供內容,客戶端查看內容。
所以,當我們訪問網頁時,大致的過程如下圖所示。
客戶端與服務端既然能夠通訊,那麽證明它們之間一定是通過某種方法進行溝通的,就像你我之間能夠進行溝通一樣。
舉例說明
你和我都說漢語,所以,當我說"蘋果"這個詞的時候,你就會想到一種水果,或者想到一個手機品牌,
但是當我對一個美國人說"蘋果"兩個字時,他可能並不能理解我在說什麽,因為他可能聽不懂漢語,
如果我想要對他表達"蘋果"這個詞,我需要說"Apple",他才會明白我說的是什麽,當我跟你聊天時,我們都說漢語,
當兩個美國人聊天時,他們都說英語,這樣,才能有效的溝通,總之,如果想要能夠順暢的溝通,
溝通雙方都必須遵守相同的協議,我們可以把漢語理解成一種協議,把英語也理解成一種協議,
只要溝通雙方都遵守相同的協議,雙方就能夠順暢的溝通,只要溝通雙方都遵守相同的協議,雙方就能夠理解對方想要做什麽。
當然,之所以拿漢語、英語舉例,是為了讓初學者能夠更加容易的理解"協議"這個詞,但是請不要錯誤的以為"協議"就是"語言",
之所以拿語言舉例,是為了方便理解,說白了,"協議"可以理解為某種規則或者某種約定,
只要大家都嚴格按照這種約定行事,世界就會正常的運轉,比如"紅燈停,綠燈行"也可以理解為一種協議,
比如在馬路上都要靠右行駛(在中國),也是一種協議,比如在小飯館,你給老板人民幣,老板給你對應的餐食,
也是一種協議,"協議"的概念稍微有一些抽象,稍微有一些寬泛,此處大概有一個印象即可,在學習的過程中,我們自己就會慢慢的理解它了。
客戶端與服務端之間,也需要遵守某些相同的協議,才能夠順暢的通訊,細心如你一定註意到了,我說的是"某些"協議,也就是說,雙方要遵守的協議不止有一種,它們需要同時遵守多種協議,才能夠正常的完成整個通訊過程。
比如http協議,剛才已經說過,不同的"層面"中,需要使用不同的協議,http協議就是應用層的一種協議,http協議是什麽意思呢?
http是HyperText Transfer Protocol的縮寫,HyperText Transfer Protocol譯為"超文本傳輸協議"。
從字面上理解,這種協議是用來傳輸"超文本"的,我們可以暫且粗暴的將"超文本"理解成我們所謂的"網頁"(這樣並不準確,但是方便理解),那麽,我們可以將http協議理解為一種"網頁傳輸協議"。
…
…
一次完整的HTTP請求過程
web服務請求處理步驟
HTTP服務通信過程
人性化HTTP請求相應圖
圖片來自:理解Http請求與響應
大致如下
域名解析 --> TCP3次握手 --> 發起http請求 --> 服務器響應http請求並傳輸數據 –> 瀏覽器解析並渲染呈現給用戶 –> TCP4次揮手
域名解析
當用戶在瀏覽器輸入https://www.cnblogs.com/時,瀏覽器會對此域名或主機進行解析,得到對應的IP地址,那麽它時怎麽進行域名解析的呢?
1、首先先去本機hosts文件查找此FQDN沒有沒定義的指向所在的IP地址條目,如果找到,就結束解析
2、如果沒有找到,回去瀏覽器器本身DNS緩存裏去尋找,找打結束解析
3、沒有找到,會去本機配置的首選DNS服務器查詢,一般這是三大運營商提供的,通過UTP53端口發起請求,這個請求是遞歸查詢,DNS服務器收到請求後,會查詢自身緩存,找到條目並且沒有過期,就返回給用戶,結束解析。如果沒有找到,它會去找根服務器,全球13個根服務器(根服務器地址本機DNS服務器內置),詢問根服務器(你知不知道一個域名叫“www.cnblogs.com”的IP地址),根回復說,(我不知道此域名的IP地址,但我知道com域的IP地址,你去詢問它吧),於是運行商提供的DNS服務器就去詢問com這個域,(你知不知道一個叫“www.cnblogs.com”域名IP地址),com域回答你說,(我不知道此域名的IP地址,但我知道“cnblogs.com域的IP地址,你去問他吧“),這是運行商DNS服務器,對cnblogs.com域發起請求詢問,(你知不知道一個叫”www.cnblogs.com“域的IP地址,它一查,發現此域,就是它負責的,就會對你說,此域是我負責的,它的IP是X.X.X.X這時運行商DNS服務器拿到地址,就會返回客戶主機內核,內核再返回給瀏覽器,到此解析結束,進行下一步。
當然這裏面還要涉及到IP –> MAC(物理地址)的解析
TCP3次握手
瀏覽器拿到域名對應的IP後,會拿一個隨機端口向WEB服務程序80端口發起TCP請求鏈接
備註:
SYN(synchronous建立聯機)
ACK(acknowledgement 確認)
PSH(push傳送)
FIN(finish結束)
RST(reset重置)
URG(urgent緊急)
Sequence number(順序號碼)
Acknowledge number(確認號碼)
舉例
A : 你好我是A,你能聽得到我說話嗎?
B : 聽到了,我是B,你能聽到我說話嗎?
A : 可以,聽到了
好建立連接,開始聊天!
過程
第一次握手:建立連接,客戶端將SYN標記為1,seq標記為x,並將SYN包發送到服務器,並進入SYN_SEND狀態,等待服務器確認;
第二次握手:服務器收到SYN,知道客戶端要建立鏈接,同時向客戶端也發送一個SYN包(SYN=1)和一個ACK包(ACK=1),隨機產生一個數seq=y,ack=x+1(客戶端的seq值x加1),來確認客戶端的SYN,並進入SYN_RECV;
第三次握手:客戶端收到服務器發來的SYN+ACK後,確認ack值,並回復服務器端一個ACK確認,發送完畢後,雙方進入ESTABLISHED狀態。
三次握手成功後,開始傳輸數據。
一個完整的三次握手也就是 請求---應答---再次確認
鏈接建立成功後,就要開始下一步,傳輸數據
HTTP請求相應處理
1、建立TCP連接:
接收或拒絕連接請求
發送請求報文
2、接收請求:
接收客戶端發來的請求報文中的信息對某資源的一次請求的過程
Web訪問響應模型(Web I/O)
1)單進程I/O模型:
啟動一個進程處理用戶請求,而且一次只處理一個,多個請求被串行響應
2)多進程I/O模型:
並行啟動多個進程,每個進程響應一個連接請求
3)復用I/O結構:
啟動一個進程,同時響應N個連接請求
實現方法: 多線程模型和事件驅動
多線程模型: 一個進程生成N個線程,每線程響應一個連接請求
事件驅動: 一個進程處理N個請求
4)復用的多進程I/O模型:
啟動M個進程,每個進程響應N個連接請求,同時接收M*N個請求
3、處理請求:
服務器對請求報文進行解析,並獲取請求的資源及請求方法等相關信息,根據方法,資源,首部和可選的主體部分對請求進行處理
HTTP常用請求方式,Method
GET、POST、HEAD、PUT、DELETE、TRACE、OPTIONS
4、訪問資源:
服務器獲取請求報文中請求的資源web服務器,即存放了web資源的服務器,負責向請求者提供對方請求的靜態資源,或動態運行後生成的資源
資源放在服務端特定的目錄下
備註:通過MAC地址和端口號確定具體的應用程序
5、構建響應報文:
一旦Web服務器識別除了資源,就執行請求方法中描述的動作,並返回響應報文。響應報文中 包含有響應狀態碼、響應首部,如果生成了響應主體的話,還包括響應主體
6、發送響應報文
向客戶端回復報文
7、記錄日誌:
最後,當事務結束時,Web服務器會在日誌文件中添加一個條目,來描述已執行的事務
備註:這中間還要涉及到https的建立過程
數據傳輸完畢就要斷開鏈接了
四次揮手
如圖
備註:
數據傳輸完畢後,雙方都可釋放連接。最開始的時候,客戶端和服務器都是處於ESTABLISHED狀態,然後客戶端主動關閉,服務器被動關閉。
過程
- 客戶端進程發出連接釋放報文,並且停止發送數據。釋放數據報文首部,FIN=1,其序列號為seq=u(等於前面已經傳送過來的數據的最後一個字節的序號加1),此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。
- 服務器收到連接釋放報文,發出確認報文,ACK=1,ack=u+1,並且帶上自己的序列號seq=v,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
- 客戶端收到服務器的確認請求後,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最後的數據)。
- 服務器將最後的數據發送完畢後,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由於在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號為seq=w,此時,服務器就進入了LAST-ACK(最後確認)狀態,等待客戶端的確認。
- 客戶端收到服務器的連接釋放報文後,必須發出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。註意此時TCP連接還沒有釋放,必須經過(最長報文段壽命)的時間後當客戶端撤銷相應的TCB後,才進入CLOSED狀態。
- 服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB後,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。
問題1-為什麽連接的時候是三次握手,關閉的時候卻是四次握手?
答:
因為當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,
SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,
所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,
我才能發送FIN報文,因此不能一起發送。故需要四步握手。
問題2-為什麽要三次握手
答:
為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。
網上轉載的例子不錯:
三次握手:
A:“餵,你聽得到嗎?”A->SYN_SEND
B:“我聽得到呀,你聽得到我嗎?”應答與請求同時發出 B->SYN_RCVD | A->ESTABLISHED
A:“我能聽到你,今天balabala……”B->ESTABLISHED
四次揮手:
A:“餵,我不說了。”A->FIN_WAIT1
B:“我知道了。等下,上一句還沒說完。Balabala…..”B->CLOSE_WAIT | A->FIN_WAIT2
B:”好了,說完了,我也不說了。”B->LAST_ACK
A:”我知道了。”A->TIME_WAIT | B->CLOSED
A等待2MSL,保證B收到了消息,否則重說一次”我知道了”,A->CLOSED
參考鏈接
1、http://www.zsythink.net/archives/76
2、https://blog.csdn.net/qzcsu/article/details/72861891
3、https://zhuanlan.zhihu.com/p/21940234
4、https://www.jianshu.com/p/c1d6a294d3c0?from=jiantop.com
HTTP-點開瀏覽器輸入網址背後發生的那點事