<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          終極解密輸入網(wǎng)址按回車到底發(fā)生了什么

          共 6501字,需瀏覽 14分鐘

           ·

          2021-05-15 20:17

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

          大致流程

          • URL 解析,解析 http 協(xié)議、端口、資源地址。
          • DNS 查詢:首先查詢本地 host,再訪問 DNS 服務(wù)器將 域名解析成 ip 地址。
          • 建立 TCP 連接。
          • 服務(wù)器收到請求后處理,并且構(gòu)造響應(yīng)返回給客戶端。
          • 客戶端接收 HTTP 報文響應(yīng)。
          • 渲染頁面,最后有可能會四次揮手斷開連接,也可能不會而是復(fù)用連接。

          重點來了

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

          繼續(xù)閱讀本文,且聽碼哥字節(jié)答疑解惑,微信搜索 “碼哥字節(jié)”,關(guān)注公眾號更多硬核。

          URL 解析

          比如 【碼哥字節(jié)】在思否發(fā)布的一篇文章的地址:https://segmentfault.com/a/1190000023475177。url 遵守的規(guī)則是這個樣子

          scheme://host.domain:port/path/filename

          每個名詞的含義如下解釋:

          • scheme 定義應(yīng)用層協(xié)議類型,比如 http、https、 ftp 等;
          • host 定義域主機(http 的默認主機是 www);
          • domain  定義因特網(wǎng)域名,比如 segmentfault.com;
          • port 主機的端口,http 默認是 80, https 默認是 443;
          • path 服務(wù)器上的資源路徑;
          • filename - 定義文檔/資源的名稱;

          DNS 查詢

          瀏覽器不能直接通過域名找到服務(wù)器,只能通過 IP 地址。

          那瀏覽器是如何通過域名查詢到我們輸入的 url 對應(yīng)的 IP 呢?

          • 瀏覽器緩存:按照一定頻率緩存 DNS 數(shù)據(jù)。
          • 操作系統(tǒng)緩存:如果瀏覽器緩存好啊不到記錄則去操作系統(tǒng)中找。
          • 路由緩存:路由器 DNS 緩存。
          • ISP 的 DNS 服務(wù)器:ISP 是互聯(lián)網(wǎng)服務(wù)提供商(Internet Service Provider)的簡稱,ISP 有專門的 DNS 服務(wù)器應(yīng)對 DNS 查詢請求。
          • 根服務(wù)器:ISP 的 DNS 服務(wù)器還找不到的話,它就會向根服務(wù)器發(fā)出請求,進行遞歸查詢(DNS 服務(wù)器先問根域名服務(wù)器.com 域名服務(wù)器的 IP 地址,然后再問 .baidu 域名服務(wù)器,依次類推)

          TCP 連接建立與斷開

          通過域名解析出 IP 地址以后就要建立 TCP/IP 連接了。

          TCP/IP 分為四層,每一層都會加上一個頭部再發(fā)送給下一層。到了接收方后,對應(yīng)的每一層則把對應(yīng)層的頭部解析拆除,丟上上一層,跟發(fā)送端的過程反過來。

          TCP/IP四層模型

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

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

          • 請求行包含請求方法、URL、協(xié)議版本

          • 請求報頭(Request Header):由 “關(guān)鍵字: 值”對組成,每行一對,關(guān)鍵字與值使用英文 “:” 分割

          • 請求體:請求參數(shù),并不是所有的請求有又請求參數(shù)。一般 get 參數(shù) 的格式 name=tom&password=1234&realName=tomson,也可以將參數(shù)放在 body 里面。

          傳輸層:TCP 傳輸報文

          在傳輸報文之前會先建立 TCP/IP 連接,也就是后面我們要說的三次握手。

          在這一層解決了數(shù)據(jù)可靠傳輸、及流量控制、擁塞控制。

          可靠傳輸

          對于發(fā)送方發(fā)送的數(shù)據(jù),接收方在接受到數(shù)據(jù)之后必須要給予確認,確認它收到了數(shù)據(jù)。如果在規(guī)定時間內(nèi),沒有給予確認則意味著接收方?jīng)]有接受到數(shù)據(jù),然后發(fā)送方對數(shù)據(jù)進行重發(fā)。

          TCP的可靠傳輸是通過確認和超時重傳的機制來實現(xiàn)的,而確認和超時重傳的具體的實現(xiàn)是通過以字節(jié)為單位的滑動窗口機制來完成。

          TCP擁塞控制

          TCP協(xié)議通過慢啟動機制、擁塞避免機制、加速遞減機制、快重傳和快恢復(fù)機制來共同實現(xiàn)擁塞控制。

          流量控制

          采用通知窗口實現(xiàn)對發(fā)送端的流量控制,通知窗口大小的單位是字節(jié)。TCP通過在TCP數(shù)據(jù)段首部的窗口字段中填入當(dāng)前設(shè)定的接收窗口(即通知窗口)的大小,用來告知對方 '我方當(dāng)前的接收窗口大小',以實現(xiàn)流量控制。

          通信雙方的發(fā)送窗口大小由雙方在連接建立的時候商定,在通信過程,雙方可以動態(tài)地根據(jù)自己的情況調(diào)整對方的發(fā)送窗口大小。

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

          將數(shù)據(jù)段打包,并加入源及目標(biāo)的 IP 地址,并且負責(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 地址都是獨一無二的,具備了一對一的能力。

          三次握手

          在傳輸層傳輸數(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] 確認上次傳輸確認。

          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 確認。
          • FIN_WAIT_2 - 表示我方已關(guān)閉連接,正在等待服務(wù)端關(guān)閉。客戶端發(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ù)器上通??梢钥吹匠汕先f的 TIME_WAIT 連接。

          服務(wù)端:

          • LISTEN - 表示當(dāng)前程序正在監(jiān)聽某個端口時。
          • SYN_RCVD - 服務(wù)端收到第 1 次握手后,進入 SYN_RCVD 狀態(tài),并回復(fù)一個 SYN+ACK(第 2 次握手),再等待對方確認。
          • 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)閉請求進行最終確認。

          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ā)送端可能因確認超時而重發(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é)議負責(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協(xié)議

          請求頭-起始行

          請求行由請求方法字段、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ù)器,我要請求根目錄下的默認文件使用的是 HTTP 1.1 協(xié)議版本”。

          頭部 Header

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

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

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

          接收到響應(yīng)文本 HTML,則開始執(zhí)行瀏覽器渲染機制。

          不同的瀏覽器渲染可能有所差異,但是基本按照以下步驟執(zhí)行:

          1. 根據(jù) HTML 解析 DOM 樹;
          2. 根據(jù) CSS 解析出 CSS 規(guī)則樹;
          3. 結(jié)合 DOM 樹與 CSS 規(guī)則樹,生成渲染樹;
          4. 根據(jù)生成的渲染樹計算每個節(jié)點的信息;
          5. 根據(jù)節(jié)點信息繪制畫面展示給用戶。
          瀏覽器渲染頁面
          推薦閱讀:

          SpringBoot開發(fā)秘籍 - 集成Graphql Query

          Linux 文件搜索神器 find 實戰(zhàn)詳解,建議收藏!

          貓撲,涼了!

          搞清楚這 10 幾個后端面試問題,工作穩(wěn)了!


          關(guān)互聯(lián)網(wǎng)全棧架構(gòu),

          瀏覽 37
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美特黄一区二区三区 | 久久在线黄色视频 | 久久久久久久久久久高清毛片一级 | 国产喷潮 | 国产丝袜足交 |