www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]詳解輸入網(wǎng)址點擊回車,后臺到底發(fā)生了什么。透析 HTTP 協(xié)議與 TCP 連接之間的千絲萬縷的關(guān)系。掌握為何是三次握手四次揮手?time_wait 存在的意義是什么?全面圖解重點問題,再也不用擔(dān)心面試被問到。 大致流程 URL 解析。 DNS 查詢。 TCP 連接。 服務(wù)器處理

詳解輸入網(wǎng)址點擊回車,后臺到底發(fā)生了什么。透析 HTTP 協(xié)議與 TCP 連接之間的千絲萬縷的關(guān)系。掌握為何是三次握手四次揮手?time_wait 存在的意義是什么?全面圖解重點問題,再也不用擔(dān)心面試被問到。

大致流程

  • URL 解析。
  • DNS 查詢。
  • TCP 連接。
  • 服務(wù)器處理請求。
  • 客戶端接收 HTTP 報文響應(yīng)。
  • 渲染頁面

重點來了

  • 如何理解 TCP 的三次握手與四次揮手?每次握手客戶端與服務(wù)端是怎樣的狀態(tài)?
  • 為何揮手會出現(xiàn) 2MSL,遇到大量 Socket 處在 TIME_WAIT 或者 CLOSE_WAIT 狀態(tài)是什么問題?
  • 三次握手與四次揮手的過程是怎樣的?
  • HTTP 的報文格式又是怎樣的?

URL 解析

地址解析:首先判斷你輸入的是一個合法的 URL 還是一個待搜索的關(guān)鍵詞,并且根據(jù)你輸入的內(nèi)容進行自動完成、字符編碼等操作。

HSTS 由于安全隱患,會使用 HSTS 強制客戶端使用 HTTPS 訪問頁面。詳見:你所不知道的 HSTS[1]。

其他操作 瀏覽器還會進行一些額外的操作,比如安全檢查、訪問限制(之前國產(chǎn)瀏覽器限制 996.)。

檢查客戶端緩存

URL解析

DNS 查詢

DNS 查詢
  1. 瀏覽器緩存:先檢查是否在緩存中,沒有則調(diào)用系統(tǒng)庫函數(shù)進行查詢。
  2. 操作系統(tǒng)緩存:操作系統(tǒng)也有自己的 DNS 緩存,但在這之前,會向檢查域名是否存在本地的 Hosts 文件里,沒有則向 DNS 服務(wù)器發(fā)送查詢請求。
  3. 路由器緩存。
  4. ISP DNS 緩存:ISP DNS 就是在客戶端電腦上設(shè)置的首選 DNS 服務(wù)器,它們在大多數(shù)情況下都會有緩存。

根域名服務(wù)器查詢

在前面所有步驟沒有緩存的情況下,本地 DNS 服務(wù)器會將請求轉(zhuǎn)發(fā)到互聯(lián)網(wǎng)上的根域,下面這個圖很好的詮釋了整個流程:

DNS遞歸查詢

需要注意的的是:

  1. 遞歸方式:一路查下去中間不返回,得到最終結(jié)果才返回信息(瀏覽器到本地 DNS 服務(wù)器的過程)
  2. 迭代方式,就是本地 DNS 服務(wù)器到根域名服務(wù)器查詢的方式。
  3. 什么是 DNS 劫持
  4. 前端 dns-prefetch 優(yōu)化

TCP 連接建立與斷開

TCP/IP 分為四層,在發(fā)送數(shù)據(jù)時,每層都要對數(shù)據(jù)進行封裝和拆解不不同的頭:

TCP/IP 連接

應(yīng)用層:發(fā)送 HTTP 請求

瀏覽器從地址欄得到服務(wù)器 IP,接著構(gòu)造一個 HTTP 報文,其中包括:

  • 請求報頭(Request Header):請求方法、目標(biāo)地址、遵循的協(xié)議等
  • 請求主體,請求參數(shù),比如 body 里面的參數(shù)

傳輸層:TCP 傳輸報文

傳輸層會發(fā)起一條到達服務(wù)器的 TCP 連接,為了方便傳輸,會對數(shù)據(jù)進行分割(以報文段為單位),并標(biāo)記編號,方便服務(wù)器接受時能夠準(zhǔn)確地還原報文信息。在建立連接前,會先進行 TCP 三次握手。

網(wǎng)絡(luò)層:IP 協(xié)議查詢 MAC 地址

將數(shù)據(jù)段打包,并加入源及目標(biāo)的 IP 地址,并且負(fù)責(zé)尋找傳輸路線。判斷目標(biāo)地址是否與當(dāng)前地址處于同一網(wǎng)絡(luò)中,是的話直接根據(jù) Mac 地址發(fā)送,否則使用路由表查找下一個地址,以及使用 ARP 協(xié)議查詢它的 Mac 地址。

鏈路層:以太網(wǎng)協(xié)議

根據(jù)以太網(wǎng)協(xié)議將數(shù)據(jù)分為以“幀”為單位的數(shù)據(jù)包,每一幀分為兩個部分:

  • 標(biāo)頭:數(shù)據(jù)包的發(fā)送者、接受者、數(shù)據(jù)類型
  • 數(shù)據(jù):數(shù)據(jù)包具體內(nèi)容

Mac 地址

以太網(wǎng)規(guī)定了連入網(wǎng)絡(luò)的所有設(shè)備都必須具備“網(wǎng)卡”接口,數(shù)據(jù)包都是從一塊網(wǎng)卡傳遞到另一塊網(wǎng)卡,網(wǎng)卡的地址就是 Mac 地址。每一個 Mac 地址都是獨一無二的,具備了一對一的能力。

主要的請求過程:

  1. 瀏覽器從地址欄中獲取服務(wù)器的 IP 和端口號;
  2. 瀏覽器與服務(wù)器之間通過 TCP 三次握手建立連接;
  3. 瀏覽器向服務(wù)器發(fā)送報文;
  4. 服務(wù)器接收報文處理,同時將響應(yīng)報文發(fā)給瀏覽器;
  5. 瀏覽器解析報文,渲染輸出到頁面;

三次握手

在傳輸層傳輸數(shù)據(jù)之前需要建立連接,也就是三次握手創(chuàng)建可靠連接。

三次握手

首先建立鏈接前需要 Server 端先監(jiān)聽端口,因此 Server 端建立鏈接前的初始狀態(tài)就是 LISTEN 狀態(tài),這時 Client 端準(zhǔn)備建立鏈接,先發(fā)送一個 SYN 同步包,發(fā)送完同步包后,Client 端的鏈接狀態(tài)變成了 SYN_SENT 狀態(tài)。Server 端收到 SYN 后,同意建立鏈接,會向 Client 端回復(fù)一個 ACK。

由于 TCP 是雙工傳輸,Server 端也會同時向 Client 端發(fā)送一個 SYN,申請 Server 向 Client 方向建立鏈接。發(fā)送完 ACK 和 SYN 后,Server 端的鏈接狀態(tài)就變成了 SYN_RCVD。

Client 收到 Server 的 ACK 后,Client 端的鏈接狀態(tài)就變成了 ESTABLISHED 狀態(tài),同時,Client 向 Server 端發(fā)送 ACK,回復(fù) Server 端的 SYN 請求。

Server 端收到 Client 端的 ACK 后,Server 端的鏈接狀態(tài)也就變成了的 ESTABLISHED 狀態(tài),此時建連完成,雙方隨時可以進行數(shù)據(jù)傳輸。

在面試時需要明白三次握手是為了建立雙向的鏈接,需要記住 Client 端和 Server 端的鏈接狀態(tài)變化。另外回答建連的問題時,可以提到 SYN 洪水攻擊發(fā)生的原因,就是 Server 端收到 Client 端的 SYN 請求后,發(fā)送了 ACK 和 SYN,但是 Client 端不進行回復(fù),導(dǎo)致 Server 端大量的鏈接處在 SYN_RCVD 狀態(tài),進而影響其他正常請求的建連??梢栽O(shè)置 tcp_synack_retries = 0 加快半鏈接的回收速度,或者調(diào)大 tcp_max_syn_backlog 來應(yīng)對少量的 SYN 洪水攻擊

四次揮手

我們只要關(guān)注 80 端口與 13743 端口建立的連接斷開過程,瀏覽器通過 13747 端口發(fā)送 [FIN, ACK] 這里是不是跟很多網(wǎng)上看到的不一樣?

  1. 其實是客戶端在發(fā)送 [FIN] 報文的時候順帶發(fā)了一個 [ACK] 確認(rèn)上次傳輸確認(rèn)。

  2. 接著服務(wù)端通過 80 端口響應(yīng)了 [ACK] ,然后立馬響應(yīng) [FIN, ACK] 表示數(shù)據(jù)傳輸完了,可以關(guān)閉連接。

  3. 最后瀏覽器通過 13743 端口 發(fā)送 [ACK] 包給服務(wù)端,客服端與服務(wù)端連接就關(guān)閉了。

具體流程如下圖抓包所示:

四次揮手

三次握手與四次揮手

TCP 連接與斷開

客戶端:

  • SYN_SENT - 客戶端發(fā)起第 1 次握手后,連接狀態(tài)為 SYN_SENT ,等待服務(wù)端內(nèi)核進行應(yīng)答,如果服務(wù)端來不及處理(例如服務(wù)端的 backlog 隊列已滿)就可以看到這種狀態(tài)的連接。
  • ESTABLISHED - 表示連接處于正常狀態(tài),可以進行數(shù)據(jù)傳送??蛻舳耸盏椒?wù)器回復(fù)的 SYN+ACK 后,對服務(wù)端的 SYN 單獨回復(fù)(第 3 次握手),連接建立完成,進入 ESTABLISHED 狀態(tài)。服務(wù)端程序收到第 3 次握手包后,也進入 ESTABLISHED 狀態(tài)。
  • FIN_WAIT_1 - 客戶端發(fā)送了關(guān)閉連接的 FIN 報文后,等待服務(wù)端回復(fù) ACK 確認(rèn)。
  • FIN_WAIT_2 - 表示我方已關(guān)閉連接,正在等待服務(wù)端關(guān)閉??蛻舳税l(fā)了關(guān)閉連接的 FIN 報文后,服務(wù)器發(fā)回 ACK 應(yīng)答,但是沒進行關(guān)閉,就會處于這種狀態(tài)。
  • TIME_WAIT - 雙方都正常關(guān)閉連接后,客戶端會維持 TIME_WAIT 一段時間,以確保最后一個 ACK 能成功發(fā)送到服務(wù)器端。停留時長為 2 倍的 MSL (報文最大生存時間),Linux 下大約是 60 秒。所以在一個頻繁建立短連接的服務(wù)器上通常可以看到成千上萬的 TIME_WAIT 連接。

服務(wù)端:

  • LISTEN - 表示當(dāng)前程序正在監(jiān)聽某個端口時。
  • SYN_RCVD - 服務(wù)端收到第 1 次握手后,進入 SYN_RCVD 狀態(tài),并回復(fù)一個 SYN+ACK(第 2 次握手),再等待對方確認(rèn)。
  • ESTABLISHED - 表示連接處于正常狀態(tài),可以進行數(shù)據(jù)傳送。完成 TCP3 次握手后,連接建立完成,進入 ESTABLISHED 狀態(tài)。
  • CLOSE_WAIT - 表示客戶端已經(jīng)關(guān)閉連接,但是本地還沒關(guān)閉,正在等待本地關(guān)閉。有時客戶端程序已經(jīng)退出了,但服務(wù)端程序由于異?;?BUG 沒有調(diào)用 close()函數(shù)對連接進行關(guān)閉,那在服務(wù)器這個連接就會一直處于 CLOSE_WAIT 狀態(tài),而在客戶機已經(jīng)不存在這個連接了。
  • LAST_ACK - 表示正在等待客戶端對服務(wù)端的關(guān)閉請求進行最終確認(rèn)。

TIME_WAIT 狀態(tài)存在的理由:

劃重點了

  • 可靠地實現(xiàn) TCP 全雙工連接的終止 在進行關(guān)閉連接四路握手協(xié)議時,最后的 ACK 是由主動關(guān)閉端發(fā)出的,如果這個最終的 ACK 丟失,服務(wù)器將重發(fā)最終的 FIN,因此客戶端必須維護狀態(tài)信息允 許它重發(fā)最終的 ACK。如 果不維持這個狀態(tài)信息,那么客戶端將響應(yīng) RST 分節(jié),服務(wù)器將此分節(jié)解釋成一個錯誤( 在 java 中會拋出 connection reset 的 SocketException)。因而,要實現(xiàn) TCP 全雙工連接的正常終 止,必須處理終止序列四個分節(jié)中任何一個分節(jié)的丟失情況,主動關(guān)閉 的客戶端必須維持狀 態(tài)信息進入 TIME_WAIT 狀態(tài)。
  • 允許老的重復(fù)分節(jié)在網(wǎng)絡(luò)中消逝 TCP 分節(jié)可能由于路由器異常而“迷途”,在迷途期間,TCP 發(fā)送端可能因確認(rèn)超時而重發(fā)這個 分節(jié),迷途的分節(jié)在路由器修復(fù)后也會被送到最終目的地,這個 原來的迷途分節(jié)就稱為 lost duplicate。在關(guān)閉一個 TCP 連接后,馬上又重新建立起一個相同的 IP 地址和端口之間的 TCP 連接,后一個連接被稱為前一個連接的化身 ( incarnation),那么有可能出現(xiàn)這種情況,前一 個連接的迷途重復(fù)分組在前一個連接終止后出現(xiàn),從而被誤解成從屬于新的化身。為了避免 這個情 況,TCP 不允許處于 TIME_WAIT 狀態(tài)的連接啟動一個新的化身, 因為 TIME_WAIT 狀 態(tài)持續(xù) 2MSL,就可以保證當(dāng)成功建立一個 TCP 連接的時 候,來自連接先前化身的重復(fù)分組已 經(jīng)在網(wǎng)絡(luò)中消逝

另外回答斷鏈的問題時,可以提到實際應(yīng)用中有可能遇到大量 Socket 處在 TIME_WAIT 或者 CLOSE_WAIT 狀態(tài)的問題。一般開啟 tcp_tw_reuse 和 tcp_tw_recycle 能夠加快 TIME-WAIT 的 Sockets 回收;而大量 CLOSE_WAIT 可能是被動關(guān)閉的一方存在代碼 bug,沒有正確關(guān)閉鏈接導(dǎo)致的。

簡單地說就是

  1. 保證 TCP 協(xié)議的全雙工連接能夠可靠關(guān)閉;
  2. 保證這次連接的重復(fù)數(shù)據(jù)段從網(wǎng)絡(luò)中消失,防止端口被重用時可能產(chǎn)生數(shù)據(jù)混淆;

服務(wù)器處理請求并響應(yīng) HTTP 報文

深入分析下 HTTP 報文到底是什么玩意。數(shù)據(jù)傳輸都是通過 TCP/IP 協(xié)議負(fù)責(zé)底層的傳輸工作, HTTP 協(xié)議基本不用操心,所謂的 “超文本傳輸協(xié)議” 似乎不怎么理會 “傳輸” 這個事情,那 HTTP 的核心又是什么呢?

比圖 TCP 報文,它在實際要傳輸?shù)臄?shù)據(jù)之前附加了一個 20 字節(jié)的頭部數(shù)據(jù),存儲 TCP 協(xié)議必須的額外信息,例如發(fā)送方的端口號、接收方的端口號、包序號、標(biāo)志位等等。

有了這個附加的 TCP 頭,數(shù)據(jù)包才能夠正確傳輸,到了目的地后把頭部去掉,就可以拿到真正的數(shù)據(jù)。這個很容易理解,設(shè)置起點與終點,不同協(xié)議貼上不同的頭部,到了對應(yīng)目的地就拆下這個頭部,提取真正的數(shù)據(jù)。

HTTP報文

與 TCP/UDP 類似需要在傳輸數(shù)據(jù)前設(shè)置一些請求頭,不同的是 HTTP 是一個 “純文本” 的協(xié)議,所有的頭都是 ASCII 碼的文本,很容易看出來是什么。

再者就是他的請求報文與響應(yīng)報文的結(jié)構(gòu)基本一樣,主要三大部分組成:

  1. 起始行(Start Line):描述請求或者響應(yīng)的基本信息。
  2. Header:使用 key-value 的形式詳細說明報文信息。
  3. 空行。
  4. 消息正文(Entity):傳輸?shù)臄?shù)據(jù),圖片、視頻、文本等都可以。

這其中前兩部分起始行和頭部字段經(jīng)常又合稱為“請求頭”或“響應(yīng)頭”,消息正文又稱為“實體”,但與“header”對應(yīng),很多時候就直接稱為“body”。

敲黑板了

HTTP 協(xié)議規(guī)定報文必須包含 Header,而且之后必須有一個 “空行”,也就是“CRLF”,十六進制的“0D0A”,可以沒有 “body”。

報文結(jié)構(gòu)如下圖所示:

HTTP報文

截取一段報文:

HTTP報文抓取

請求頭-起始行

請求行由請求方法字段、URL 字段和 HTTP 協(xié)議版本字段 3 個字段組成,它們用空格分隔。例如,GET / HTTP/1.1。

HTTP 協(xié)議的請求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。

GET 是請求方法, “/” 是請求的目標(biāo)資源,“HTTP/1.1” 請求協(xié)議版本號。

GET / HTTP/1.1翻譯成文字大概就是:“hello,服務(wù)器,我要請求根目錄下的默認(rèn)文件使用的是 HTTP 1.1 協(xié)議版本”。

頭部 Header

第二部分就是 Header,組成形式是 key:value,使用自定義頭需要注意事項:

  1. header 字段不區(qū)分大小寫,通常是首字母大寫;
  2. 字段名不允許有空格,可以使用 “-”,不能使用 “_”;
  3. 字段名必須緊接著 “:”,不能有空格,但是 “:” 后面可以有空格。
  4. 字段名順序沒有意義;

瀏覽器接收響應(yīng)并渲染數(shù)據(jù)

瀏覽器接收到來自服務(wù)器的響應(yīng)資源后,會對資源進行分析。首先查看 Response header,根據(jù)不同狀態(tài)碼做不同的事(比如上面提到的重定向)。如果響應(yīng)資源進行了壓縮(比如 gzip),還需要進行解壓。然后,對響應(yīng)資源做緩存。接下來,根據(jù)響應(yīng)資源里的 MIME[3] 類型去解析響應(yīng)內(nèi)容(比如 HTML、Image 各有不同的解析方式)。


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉
關(guān)閉