前言 Internet最早來源於美國國防部ARPANet,1969年投入運行,到現在已有很長一段路了,各位想要瞭解發展史可以百度下,這裡就不多說了。 現如今當我們想要獲取一些資料,首先是打開某個瀏覽器,在地址欄輸入地址,想要的信息出現在你的面前。 大家有沒有想過輸入地址就能返回給你想要的信息是怎麼實 ...
前言
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