HTTP-點開瀏覽器輸入網址背後發生的那點事

来源:https://www.cnblogs.com/xsuid/archive/2018/08/10/9451811.html
-Advertisement-
Play Games

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


 

前言

Internet最早來源於美國國防部ARPANet,1969年投入運行,到現在已有很長一段路了,各位想要瞭解發展史可以百度下,這裡就不多說了。

現如今當我們想要獲取一些資料,首先是打開某個瀏覽器,在地址欄輸入地址,想要的信息出現在你的面前。

大家有沒有想過輸入地址就能返回給你想要的信息是怎麼實現的呢?

下麵就來簡單說下它的實現流程,不過在這之前先來瞭解下HTTP基本概念如下

HTTP基本概念

在這引用http://www.zsythink.net/archives/76

這是一篇為初學者準備的文章,所以作者會儘量從基礎出發,儘量細緻的描述每一個細節,以求讓初學者不會一頭霧水,有一定基礎的同學就不用看了,以免浪費你的時間。

 

假設博主今天春心蕩漾,想要訪問一些不可描述的小網站,於是,博主悄悄的打開了瀏覽器,在瀏覽器的地址欄中輸入了一個小網站的網址,

此處假設這個小網站的網址為 www.zsythink.net ,當博主輸入了這個網址以後,瀏覽器中就顯示了博主想要看到的內容,整個過程如下圖所示。

   201803

那麼,瀏覽器返回給我們的內容是怎麼產生的呢?

這些內容肯定不是憑空產生的,而是有人為我們準備了這些內容,當我們在瀏覽器的地址欄中輸入網址以後,

這些提前準備好的內容即可返回到瀏覽器中,以便有需要的人能夠查看到這些內容,

而查看這些內容的人就是我們平常所說的"客戶",客戶往往會通過"客戶端程式"去請求、查看這些內容,

我們最常使用的客戶端程式就是瀏覽器了,所以,在之後的http相關的文章中,

如果沒有特別說明,我們所說的"客戶端"就是指"瀏覽器",我們使用客戶端去查看我們想要的內容,

而提供內容的一端被稱為"服務端",當作為客戶時,我們需要在電腦上安裝客戶端軟體(即瀏覽器),

通過客戶端軟體查看我們想要的內容,而作為提供內容的人,也需要在服務端的電腦上安裝對應的軟體,

才能為我們提供服務,而服務端的電腦就是我們常說的"伺服器",安裝在伺服器上的、為我們提供內容的軟體被稱之為"web伺服器軟體"。

 

所以,綜上所述,我們可以瞭解到如下名詞

註:如下名詞的解釋均針對http而言,在後面的文章中我們會解釋什麼是http,此處不用糾結

客戶端:客戶端通常是指瀏覽器,比如谷歌瀏覽器、火狐瀏覽器、IE等,瀏覽器安裝在客戶使用的電腦上,所以,在描述http時,客戶端通常也代指那些安裝了瀏覽器的電腦。

服務端:服務端通常是指那些安裝了"web服務軟體"的電腦,這些服務端的電腦被稱為伺服器。

 

沒錯,聰明如你一定想到了,說白了,客戶端與服務端就是兩臺電腦,分別安裝了不同的軟體,服務端提供內容,客戶端查看內容。201801

 

所以,當我們訪問網頁時,大致的過程如下圖所示。

 

201802

 

客戶端與服務端既然能夠通訊,那麼證明它們之間一定是通過某種方法進行溝通的,就像你我之間能夠進行溝通一樣。

舉例說明

你和我都說漢語,所以,當我說"蘋果"這個詞的時候,你就會想到一種水果,或者想到一個手機品牌,

但是當我對一個美國人說"蘋果"兩個字時,他可能並不能理解我在說什麼,因為他可能聽不懂漢語,

如果我想要對他表達"蘋果"這個詞,我需要說"Apple",他才會明白我說的是什麼,當我跟你聊天時,我們都說漢語,

當兩個美國人聊天時,他們都說英語,這樣,才能有效的溝通,總之,如果想要能夠順暢的溝通,

溝通雙方都必須遵守相同的協議,我們可以把漢語理解成一種協議,把英語也理解成一種協議,

只要溝通雙方都遵守相同的協議,雙方就能夠順暢的溝通,只要溝通雙方都遵守相同的協議,雙方就能夠理解對方想要做什麼。

當然,之所以拿漢語、英語舉例,是為了讓初學者能夠更加容易的理解"協議"這個詞,但是請不要錯誤的以為"協議"就是"語言",

之所以拿語言舉例,是為了方便理解,說白了,"協議"可以理解為某種規則或者某種約定,

只要大家都嚴格按照這種約定行事,世界就會正常的運轉,比如"紅燈停,綠燈行"也可以理解為一種協議,

比如在馬路上都要靠右行駛(在中國),也是一種協議,比如在小飯館,你給老闆人民幣,老闆給你對應的餐食,

也是一種協議,"協議"的概念稍微有一些抽象,稍微有一些寬泛,此處大概有一個印象即可,在學習的過程中,我們自己就會慢慢的理解它了。

 

客戶端與服務端之間,也需要遵守某些相同的協議,才能夠順暢的通訊,細心如你一定註意到了,我說的是"某些"協議,也就是說,雙方要遵守的協議不止有一種,它們需要同時遵守多種協議,才能夠正常的完成整個通訊過程。

 

比如http協議,剛纔已經說過,不同的"層面"中,需要使用不同的協議,http協議就是應用層的一種協議,http協議是什麼意思呢?

http是HyperText Transfer Protocol的縮寫,HyperText Transfer Protocol譯為"超文本傳輸協議"。

從字面上理解,這種協議是用來傳輸"超文本"的,我們可以暫且粗暴的將"超文本"理解成我們所謂的"網頁"(這樣並不准確,但是方便理解),那麼,我們可以將http協議理解為一種"網頁傳輸協議"。

一次完整的HTTP請求過程

web服務請求處理步驟

image

HTTP服務通信過程

image

人性化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請求鏈接

image

備註:

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連接:

接收或拒絕連接請求

發送請求報文

image

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、處理請求:

伺服器對請求報文進行解析,並獲取請求的資源及請求方法等相關信息,根據方法,資源,首部和可選的主體部分對請求進行處理

image

HTTP常用請求方式,Method
GET、POST、HEAD、PUT、DELETE、TRACE、OPTIONS

4、訪問資源:

伺服器獲取請求報文中請求的資源web伺服器,即存放了web資源的伺服器,負責向請求者提供對方請求的靜態資源,或動態運行後生成的資源

資源放在服務端特定的目錄下

備註:通過MAC地址和埠號確定具體的應用程式

5、構建響應報文:

一旦Web伺服器識別除了資源,就執行請求方法中描述的動作,並返迴響應報文。響應報文中 包含有響應狀態碼、響應首部,如果生成了響應主體的話,還包括響應主體

image

6、發送響應報文

向客戶端回覆報文

7、記錄日誌:

最後,當事務結束時,Web伺服器會在日誌文件中添加一個條目,來描述已執行的事務

備註:這中間還要涉及到https的建立過程

數據傳輸完畢就要斷開鏈接了

四次揮手

如圖

image

備註:

數據傳輸完畢後,雙方都可釋放連接。最開始的時候,客戶端和伺服器都是處於ESTABLISHED狀態,然後客戶端主動關閉,伺服器被動關閉。

過程

  1. 客戶端進程發出連接釋放報文,並且停止發送數據。釋放數據報文首部,FIN=1,其序列號為seq=u(等於前面已經傳送過來的數據的最後一個位元組的序號加1),此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。
  2. 伺服器收到連接釋放報文,發出確認報文,ACK=1,ack=u+1,並且帶上自己的序列號seq=v,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP伺服器通知高層的應用進程,客戶端向伺服器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是伺服器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
  3. 客戶端收到伺服器的確認請求後,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待伺服器發送連接釋放報文(在這之前還需要接受伺服器發送的最後的數據)。
  4. 伺服器將最後的數據發送完畢後,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由於在半關閉狀態,伺服器很可能又發送了一些數據,假定此時的序列號為seq=w,此時,伺服器就進入了LAST-ACK(最後確認)狀態,等待客戶端的確認。
  5. 客戶端收到伺服器的連接釋放報文後,必鬚髮出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。註意此時TCP連接還沒有釋放,必須經過(最長報文段壽命)的時間後當客戶端撤銷相應的TCB後,才進入CLOSED狀態。
  6. 伺服器只要收到了客戶端發出的確認,立即進入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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 忽然想起之前一直想寫個簡單的計算器,今天就寫了一下,界面有些簡陋,但是基本功能實現沒有問題 以下是源碼: ...
  • Ubuntu16.04下配置ssh免密登錄 環境準備:新建兩台虛擬機,而且兩台虛擬機上都裝有Ubuntu16.04的系統,使兩台虛擬機之間保持互通狀態。分別為兩台虛擬機命名為A,B。假設我們要使A虛擬機免密登錄B虛擬機。 1.在A虛擬機的普通用戶的終端下輸入如下命令: 然後一直按回車到結束。這時在/ ...
  • 在項目中,有些模塊是開源的,沒有源碼或者不能改動源碼,想要修複、優化裡面的Bug,這時就需要用到patch了。 1. 生成patch 製作補丁有兩種法法,diff和quilt。 1.1 diff方法製作patch 1.1.1 示例 l 第一步,創建兩個文件,test.c源文件和修改後的文件test_ ...
  • 隨著時間的推移,硬碟驅動器上的文件會碎片化,並且電腦速度會變慢,因為它必須檢查驅動器上的多個位置以查找這些文件。要使電腦更高效地運行,請使用Windows中的內置工具對這些文件進行碎片整理。這是你應該怎麼做以及何時做的。 Windows 10,如之前的Windows 8和Windows 7免費下 ...
  • 因為公司業務需求,可能涉及到更改ssh遠程的埠號,用下麵方法輕鬆解決,廢話不多說! 1.打開ssh埠配置文件:vim /etc/ssh/sshd_config,找到如下圖所示的埠,改為自己想改的埠,也可以同時打開多個埠: 2.需要關閉SELinux,打開配置文件:vim /etc/seli ...
  • 繼昨天伺服器上應用 CPU占用過高 後面該應用宕掉了以後 java 一次CPU占用過高問題的排查及解決 今天又出現了更嚴重的問題 昨天解決完問題 今天早些時候 出現了系統無法登錄 查詢日誌定位應該數資料庫的問題 後面發現是磁碟滿了 其實還是昨天的出現問題的導致, 死迴圈刷了特別多的日誌,,導致磁碟空 ...
  • 環境 lunix(ubuntu) 1:添加文件 在 /etc/apt/sources.list.d/gitlab-ce.list 中添加一行 2:開始安裝 3:修改配置 /etc/gitlab/gitlab.rb 中修改 external_url (如 : external_url 'http:// ...
  • 將兩伺服器通訊問題擴展到多伺服器通訊問題,需要解決定址以及復用/分用問題,這就是數據鏈路層的主要作用。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...