圖解網(wǎng)絡(luò)請(qǐng)求

圖解網(wǎng)絡(luò)-小林coding-v3.0

105個(gè)想法

一、基礎(chǔ)篇

>> 數(shù)據(jù)鏈路層(Data Link Layer),它主要為網(wǎng)絡(luò)層提供鏈路級(jí)別傳輸?shù)姆?wù)

>> 路由器計(jì)算出了下一個(gè)目的地 IP 地址,再通過 ARP 協(xié)議找到該目的地的 MAC 地址,這樣就知道這個(gè) IP 地址是哪個(gè)設(shè)備的了

>> 當(dāng)數(shù)據(jù)準(zhǔn)備要從設(shè)備發(fā)送到網(wǎng)絡(luò)時(shí),需要把數(shù)據(jù)包轉(zhuǎn)換成電信號(hào),讓其可以在物理介質(zhì)中傳輸,這一層就是物理層(Physical Layer),它主要是為數(shù)據(jù)鏈路層提供二進(jìn)制傳輸?shù)姆?wù)。

二、HTTP 篇

>> HTTP 是一個(gè)在計(jì)算機(jī)世界里專門在「兩點(diǎn)」之間「傳輸」文字、圖片、音頻、視頻等「超文本」數(shù)據(jù)的「約定和規(guī)范」。

>> GET 和 POST 方法都是安全和冪等的嗎?先說明下安全和冪等的概念:在 HTTP 協(xié)議里,所謂的「安全」是指請(qǐng)求方法不會(huì)「破壞」服務(wù)器上的資源。所謂的「冪等」,意思是多次執(zhí)行相同的操作,結(jié)果都是「相同」的。那么很明顯 GET 方法就是安全且冪等的,因?yàn)樗恰钢蛔x」操作,無論操作多少次,服務(wù)器上的數(shù)據(jù)都是安全的,且每次的結(jié)果都是相同的。POST 因?yàn)槭恰感略龌蛱峤粩?shù)據(jù)」的操作,會(huì)修改服務(wù)器上的資源,所以是不安全的,且多次提交數(shù)據(jù)就會(huì)創(chuàng)建多個(gè)資源,所以不是冪等的。

>> HTTP/1.1 采用了長連接的方式,這使得管道(pipeline)網(wǎng)絡(luò)傳輸成為了可能。即可在同一個(gè) TCP 連接里面,客戶端可以發(fā)起多個(gè)請(qǐng)求,只要第一個(gè)請(qǐng)求發(fā)出去了,不必等其回來,就可以發(fā)第二個(gè)請(qǐng)求出去,可以減少整體的響應(yīng)時(shí)間。舉例來說,客戶端需要請(qǐng)求兩個(gè)資源。以前的做法是,在同一個(gè)TCP連接里面,先發(fā)送 A 請(qǐng)求,然后等待服務(wù)器做出回應(yīng),收到后再發(fā)出 B 請(qǐng)求。管道機(jī)制則是允許瀏覽器同時(shí)發(fā)出 A 請(qǐng)求和 B 請(qǐng)求。

>> 但是服務(wù)器還是按照順序,先回應(yīng) A 請(qǐng)求,完成后再回應(yīng) B 請(qǐng)求。要是前面的回應(yīng)特別慢,后面就會(huì)有許多請(qǐng)求排隊(duì)等著。這稱為「隊(duì)頭堵塞」。3. 隊(duì)頭阻塞

>> 「請(qǐng)求 - 應(yīng)答」的模式加劇了 HTTP 的性能問題。因?yàn)楫?dāng)順序發(fā)送的請(qǐng)求序列中的一個(gè)請(qǐng)求因?yàn)槟撤N原因被阻塞時(shí),在后面排隊(duì)的所有請(qǐng)求也一同被阻塞了,會(huì)招致客戶端一直請(qǐng)求不到數(shù)據(jù),這也就是「隊(duì)頭阻塞」。好比上班的路上塞車

>> HTTPS 是如何建立連接的?其間交互了什么?SSL/TLS 協(xié)議基本流程:客戶端向服務(wù)器索要并驗(yàn)證服務(wù)器的公鑰。雙方協(xié)商生產(chǎn)「會(huì)話秘鑰」。雙方采用「會(huì)話秘鑰」進(jìn)行加密通信。前兩步也就是 SSL/TLS 的建立過程,也就是握手階段。SSL/TLS 的「握手階段」涉及四次通信,可見下圖:[插圖]SSL/TLS 協(xié)議建立的詳細(xì)流程:1. ClientHello首先,由客戶端向服務(wù)器發(fā)起加密通信請(qǐng)求,也就是 ClientHello 請(qǐng)求。

>> 在這一步,客戶端主要向服務(wù)器發(fā)送以下信息:(1)客戶端支持的 SSL/TLS 協(xié)議版本,如 TLS 1.2 版本。(2)客戶端生產(chǎn)的隨機(jī)數(shù)(Client Random),后面用于生產(chǎn)「會(huì)話秘鑰」。(3)客戶端支持的密碼套件列表,如 RSA 加密算法。

>> 2. SeverHello服務(wù)器收到客戶端請(qǐng)求后,向客戶端發(fā)出響應(yīng),也就是 SeverHello。服務(wù)器回應(yīng)的內(nèi)容有如下內(nèi)容:(1)確認(rèn) SSL/ TLS 協(xié)議版本,如果瀏覽器不支持,則關(guān)閉加密通信。(2)服務(wù)器生產(chǎn)的隨機(jī)數(shù)

>> (Server Random),后面用于生產(chǎn)「會(huì)話秘鑰」。(3)確認(rèn)的密碼套件列表,如 RSA 加密算法。(4)服務(wù)器的數(shù)字證書。3.客戶端回應(yīng)

>> 客戶端收到服務(wù)器的回應(yīng)之后,首先通過瀏覽器或者操作系統(tǒng)中的 CA 公鑰,確認(rèn)服務(wù)器的數(shù)字證書的真實(shí)性。如果證書沒有問題,客戶端會(huì)從數(shù)字證書中取出服務(wù)器的公鑰,然后使用它加密報(bào)文,向服務(wù)器發(fā)送如下信息:(1)一個(gè)隨機(jī)數(shù)(pre-master key)。該隨機(jī)數(shù)會(huì)被服務(wù)器公鑰加密。(2)加密通信算法改變通知,表示隨后的信息都將用「會(huì)話秘鑰」加密

>> 通信。(3)客戶端握手結(jié)束通知,表示客戶端的握手階段已經(jīng)結(jié)束。這一項(xiàng)同時(shí)把之前所有內(nèi)容的發(fā)生的數(shù)據(jù)做個(gè)摘要,用來供服務(wù)端校驗(yàn)。上面第一項(xiàng)的隨機(jī)數(shù)是整個(gè)握手階段的第三個(gè)隨機(jī)數(shù),這樣服務(wù)器和客戶端就同時(shí)有三個(gè)隨機(jī)數(shù),接著就用雙方協(xié)商的加密算法,各自生成本次通信的「會(huì)話秘鑰」。4. 服務(wù)器的最后回應(yīng)服務(wù)器收到客戶端的第三個(gè)隨機(jī)數(shù)(pre-master key)之后,通過協(xié)商的加密算法,計(jì)算出本次通信的「會(huì)話秘鑰」。然后,向客戶端發(fā)生最后的信息:(1)加密通信算法改變通知,表示隨后的信息都將用「會(huì)話秘鑰」加密通信。

>> (2)服務(wù)器握手結(jié)束通知,表示服務(wù)器的握手階段已經(jīng)結(jié)束。這一項(xiàng)同時(shí)把之前所有內(nèi)容的發(fā)生的數(shù)據(jù)做個(gè)摘要,用來供客戶端校驗(yàn)。至此,整個(gè) SSL/TLS 的握手階段全部結(jié)束。接下來,客戶端與服務(wù)器進(jìn)入加密通信,就完全是使用普通的 HTTP 協(xié)議,只不過用「會(huì)話秘鑰」加密內(nèi)容。

>> HTTP/2 相比 HTTP/1.1 性能上的改進(jìn):1. 頭部壓縮HTTP/2 會(huì)壓縮頭(Header)如果你同時(shí)發(fā)出多個(gè)請(qǐng)求,他們的頭是一樣的或是相似的,那么,協(xié)議會(huì)幫你消除重復(fù)的部分。這就是所謂的 HPACK 算法:在客戶端和服務(wù)器同時(shí)維護(hù)一張頭信息表,所有字段都會(huì)存入這個(gè)表,生成一個(gè)索引號(hào),以后就不發(fā)送同樣字段了,只發(fā)送索引號(hào),這樣就提高速度了。2. 二進(jìn)制格式HTTP/2 不再像 HTTP/1.1 里的純文本形式的報(bào)文,而是全面采用了二進(jìn)制格式,頭信息和數(shù)據(jù)體都是二進(jìn)制,并且統(tǒng)稱為幀(frame):頭信息幀和數(shù)據(jù)幀。

>> [插圖]這樣雖然對(duì)人不友好,但是對(duì)計(jì)算機(jī)非常友好,因?yàn)橛?jì)算機(jī)只懂二進(jìn)制,那么收到報(bào)文后,無需再將明文的報(bào)文轉(zhuǎn)成二進(jìn)制,而是直接解析二進(jìn)制報(bào)文,這增加了數(shù)據(jù)傳輸?shù)男省?br>

>> 3. 數(shù)據(jù)流HTTP/2 的數(shù)據(jù)包不是按順序發(fā)送的,同一個(gè)連接里面連續(xù)的數(shù)據(jù)包,可能屬于不同的回應(yīng)。因此,必須要對(duì)數(shù)據(jù)包做標(biāo)記,指出它屬于哪個(gè)回應(yīng)。每個(gè)請(qǐng)求或回應(yīng)的所有數(shù)據(jù)包,稱為一個(gè)數(shù)據(jù)流(Stream)。每個(gè)數(shù)據(jù)流都標(biāo)記著一個(gè)獨(dú)一無二的編號(hào),其中規(guī)定客戶端發(fā)出的數(shù)據(jù)流編號(hào)為奇數(shù), 服務(wù)器發(fā)出的數(shù)據(jù)流編號(hào)為偶數(shù)客戶端還可以指定數(shù)據(jù)流的優(yōu)先級(jí)。優(yōu)先級(jí)高的請(qǐng)求,服務(wù)器就先響應(yīng)該請(qǐng)求。

>> 4. 多路復(fù)用HTTP/2 是可以在一個(gè)連接中并發(fā)多個(gè)請(qǐng)求或回應(yīng),而不用按照順序一一對(duì)應(yīng)。移除了 HTTP/1.1 中的串行請(qǐng)求,不需要排隊(duì)等待,也就不會(huì)再出現(xiàn)「隊(duì)頭阻塞」問題,降低了延遲,大幅度提高了連接的利用率。

>> 5. 服務(wù)器推送HTTP/2 還在一定程度上改善了傳統(tǒng)的「請(qǐng)求 - 應(yīng)答」工作模式,服務(wù)不

>> 再是被動(dòng)地響應(yīng),也可以主動(dòng)向客戶端發(fā)送消息。

>> HTTP/2 有哪些缺陷?HTTP/3 做了哪些優(yōu)化?HTTP/2 主要的問題在于,多個(gè) HTTP 請(qǐng)求在復(fù)用一個(gè) TCP 連接,下層的 TCP 協(xié)議是不知道有多少個(gè) HTTP 請(qǐng)求的。所以一旦發(fā)生了丟包現(xiàn)象,就會(huì)觸發(fā) TCP 的重傳機(jī)制,這樣在一個(gè) TCP 連接中的所有的 HTTP 請(qǐng)求都必須等待這個(gè)丟了的包被重傳回來。HTTP/1.1 中的管道( pipeline)傳輸

>> 中如果有一個(gè)請(qǐng)求阻塞了,那么隊(duì)列后請(qǐng)求也統(tǒng)統(tǒng)被阻塞住了HTTP/2 多個(gè)請(qǐng)求復(fù)用一個(gè)TCP連接,一旦發(fā)生丟包,就會(huì)阻塞住所有的 HTTP 請(qǐng)求。這都是基于 TCP 傳輸層的問題,所以 HTTP/3 把 HTTP 下層的 TCP 協(xié)議改成了 UDP!

>> 使用 KeepAlive 將 HTTP/1.1 從短連接改成長鏈接。

>> 如何減少 HTTP 請(qǐng)求次數(shù)?減少 HTTP 請(qǐng)求次數(shù)自然也就提升了 HTTP 性能,可以從這 3 個(gè)方面入手:

>> 減少重定向請(qǐng)求次數(shù);合并請(qǐng)求;延遲發(fā)送請(qǐng)求;

>> [插圖]

>> 如果重定向的工作交由代理服務(wù)器完成,就能減少 HTTP 請(qǐng)求次數(shù)了,如下圖:[插圖]而且當(dāng)代理服務(wù)器知曉了重定向規(guī)則后,可以進(jìn)一步減少消息傳遞次數(shù),如下圖:[插圖]

>> 其中,301 和 308 響應(yīng)碼是告訴客戶端可以將重定向響應(yīng)緩存到本地磁盤,之后客戶端就自動(dòng)用 url2 替代 url1 訪問服務(wù)器的資源。

>> 合并請(qǐng)求的方式就是合并資源,以一個(gè)大資源的請(qǐng)求替換多個(gè)小資源的請(qǐng)求。

>> gzip 的壓縮效率相比 Google 推出的 Brotli 算法還是差點(diǎn)意思,也就是上文中的 br,所以如果可以,服務(wù)器應(yīng)該選擇壓縮效率更高的 br 壓縮算法。

>> 這次主要從 3 個(gè)方面介紹了優(yōu)化 HTTP/1.1 協(xié)議的思路。第一個(gè)思路是,通過緩存技術(shù)來避免發(fā)送 HTTP 請(qǐng)求。客戶端收到第一個(gè)請(qǐng)求的響應(yīng)后,可以將其緩存在本地磁盤,下次請(qǐng)求的時(shí)候,如果緩存沒過期,就直接讀取本地緩存的響應(yīng)數(shù)據(jù)。如果緩存過期,客戶端發(fā)送請(qǐng)求的時(shí)候帶上響應(yīng)數(shù)據(jù)的摘要,服務(wù)器比對(duì)后發(fā)現(xiàn)資源沒有變化,就發(fā)出不帶包體的 304 響應(yīng),告訴客戶端緩存的響應(yīng)仍然有效。第二個(gè)思路是,減少 HTTP 請(qǐng)求的次數(shù),有以下的方法:將原本由客戶端處理的重定向請(qǐng)求,交給代理服務(wù)器處理,這樣可以減少重定向請(qǐng)求的次數(shù);將多個(gè)小資源合并成一個(gè)大資源再傳輸,能夠減少 HTTP 請(qǐng)求次數(shù)以及 頭部的重復(fù)傳輸,再來減少 TCP 連接數(shù)量,進(jìn)而省去 TCP 握手和慢啟動(dòng)的網(wǎng)絡(luò)消耗;按需訪問資源,只訪問當(dāng)前用戶看得到/用得到的資源,當(dāng)客戶往下滑動(dòng),再訪問接下來的資源,以此達(dá)到延遲請(qǐng)求,也就減少了同一時(shí)間的 HTTP 請(qǐng)求次數(shù)。第三思路是,通過壓縮響應(yīng)資源,降低傳輸資源的大小,從而提高傳輸效率,所以應(yīng)當(dāng)選擇更優(yōu)秀的壓縮算法。

>> HTTPS 是應(yīng)用層協(xié)議,需要先完成 TCP 連接建立,然后走 TLS 握手過程后,才能建立通信安全的連接。

>> 因?yàn)榭紤]到性能的問題,所以雙方在加密應(yīng)用信息時(shí)使用的是對(duì)稱加密密鑰,而對(duì)稱加密密鑰是不能被泄漏的,為了保證對(duì)稱加密密鑰的安全性,所以使用非對(duì)稱加密的方式來保護(hù)對(duì)稱加密密鑰的協(xié)商,這個(gè)工作就是密鑰交換算法負(fù)責(zé)的。接下來,我們就以最簡單的 RSA 密鑰交換算法,來看看它的 TLS 握手過程。

>> 數(shù)字證書簽發(fā)和驗(yàn)證流程如下圖圖所示,為數(shù)字證書簽發(fā)和驗(yàn)證流程:[插圖]CA 簽發(fā)證書的過程,如上圖左邊部分:首先 CA 會(huì)把持有者的公鑰、用途、

這里由于黑客無法拿到私鑰所以無法對(duì),篡改后的內(nèi)容做簽名

>[插圖]

>> 頒發(fā)者、有效時(shí)間等信息打成一個(gè)包,然后對(duì)這些信息進(jìn)行 Hash 計(jì)算,得到一個(gè) Hash 值;然后 CA 會(huì)使用自己的私鑰將該 Hash 值加密,生成 Certificate Signature,也就是 CA 對(duì)證書做了簽名;最后將 Certificate Signature 添加在文件證書上,形成數(shù)字證書;客戶端校驗(yàn)服務(wù)端的數(shù)字證書的過程,如上圖右邊部分:首先客戶端會(huì)使用同樣的 Hash 算法獲取該證書的 Hash 值 H1;通常瀏覽器和操作系統(tǒng)中集成了 CA 的公鑰信息,瀏覽器收到證書后可以使用 CA 的公鑰解密 Certificate Signature 內(nèi)容,得到一個(gè) Hash 值 H2 ;最后比較 H1 和 H2,如果值相同,則為可信賴的證書,否則則認(rèn)為證書不可信。

>> RSA 算法的缺陷使用 RSA 密鑰協(xié)商算法的最大問題是不支持前向保密。因?yàn)榭蛻舳藗鬟f隨機(jī)數(shù)(用于生成對(duì)稱加密密鑰的條件之一)給服務(wù)端時(shí)使用的是公鑰加密的,服務(wù)端收到到后,會(huì)用私鑰解密得到隨機(jī)數(shù)。所以一旦服務(wù)端的私鑰泄漏了,過去被第三方截獲的所有 TLS 通訊密文都會(huì)被破解。

>> [插圖]

>> HTTPS 常用的密鑰交換算法有兩種,分別是 RSA 和 ECDHE 算法。

>> 分析性能損耗既然要對(duì) HTTPS 優(yōu)化,那得清楚哪些步驟會(huì)產(chǎn)生性能消耗,再對(duì)癥下藥。產(chǎn)生性能消耗的兩個(gè)環(huán)節(jié):第一個(gè)環(huán)節(jié), TLS 協(xié)議握手過程;第二個(gè)環(huán)節(jié),握手后的對(duì)稱加密報(bào)文傳輸。

>> 第一個(gè)環(huán)節(jié),TLS 協(xié)議握手過程不僅增加了網(wǎng)絡(luò)延時(shí)(最長可以花費(fèi)掉 2 RTT),而且握手過程中的一些步驟也會(huì)產(chǎn)生性能損耗

>> 對(duì)于服務(wù)器的證書應(yīng)該選擇橢圓曲線(ECDSA)證書,而不是 RSA 證書,因?yàn)樵谙嗤踩珡?qiáng)度下, ECC 密鑰長度比 RSA 短的多。

>> OCSP Stapling于是為了解決這一個(gè)網(wǎng)絡(luò)開銷,就出現(xiàn)了 OCSP Stapling,其原理是:服務(wù)器向 CA 周期性地查詢證書狀態(tài),獲得一個(gè)帶有時(shí)間戳和簽名的響應(yīng)結(jié)果并緩存它。[插圖]當(dāng)有客戶端發(fā)起連接請(qǐng)求時(shí),服務(wù)器會(huì)把這個(gè)「響應(yīng)結(jié)果」在 TLS 握手過程中發(fā)給客戶端。由于有簽名的存在,服務(wù)器無法篡改,因此客戶端就能得知證書是否已被吊銷了,這樣客戶端就不需要再去查詢。

>> [插圖]

當(dāng)有客戶端發(fā)起連接請(qǐng)求時(shí),服務(wù)器會(huì)把這個(gè)「響應(yīng)結(jié)果」在 TLS 握手過程中發(fā)給客戶端。由于有簽名的存在,服務(wù)器無法篡改,因此客戶端就能得知證書是否已被吊銷了,這樣客戶端就不需要再去查詢。

會(huì)話復(fù)用

TLS 握手的目的就是為了協(xié)商出會(huì)話密鑰,也就是對(duì)稱加密密鑰,那我們?nèi)绻覀儼咽状?TLS 握手協(xié)商的對(duì)稱加密密鑰緩存起來,待下次需要建立 HTTPS 連接時(shí),直接「復(fù)用」這個(gè)密鑰,不就減少 TLS 握手的性能損耗了嗎?

>> 會(huì)話復(fù)用TLS 握手的目的就是為了協(xié)商出會(huì)話密鑰,也就是對(duì)稱加密密鑰,那我們?nèi)绻覀儼咽状?TLS 握手協(xié)商的對(duì)稱加密密鑰緩存起來,待下次需要建立 HTTPS 連接時(shí),直接「復(fù)用」這個(gè)密鑰,不就減少 TLS 握手的性能損耗了嗎?

>> 會(huì)話復(fù)用分兩種:第一種叫 Session ID;第二種叫 Session Ticket;

>> Session IDSession ID 的工作原理是,客戶端和服務(wù)器首次 TLS 握手連接后,雙方會(huì)在內(nèi)存緩存會(huì)話密鑰,并用唯一的 Session ID 來標(biāo)識(shí),Session ID 和會(huì)話密鑰相當(dāng)于 key-value 的關(guān)系。當(dāng)客戶端再次連接時(shí),hello 消息里會(huì)帶上 Session ID,服務(wù)器收到后就會(huì)從內(nèi)存找,如果找到就直接用該會(huì)話密鑰恢復(fù)會(huì)話狀態(tài),跳過其余的過程,只用一個(gè)消息往返就可以建立安全通信。當(dāng)然為了安全性,內(nèi)存中的會(huì)話密鑰會(huì)定期失效。[插圖]

>> 它有兩個(gè)缺點(diǎn):服務(wù)器必須保持每一個(gè)客戶端的會(huì)話密鑰,隨著客戶端的增多,服務(wù)器的內(nèi)存壓力也會(huì)越大?,F(xiàn)在網(wǎng)站服務(wù)一般是由多臺(tái)服務(wù)器通過負(fù)載均衡提供服務(wù)的,客戶端再次連接不一定會(huì)命中上次訪問過的服務(wù)器,于是還要走完整的 TLS 握手過程;

>> Session Ticket為了解決 Session ID 的問題,就出現(xiàn)了 Session Ticket,服務(wù)器不再緩存每個(gè)客戶端的會(huì)話密鑰,而是把緩存的工作交給了客戶端,類似于 HTTP 的 Cookie。

>> 對(duì)于硬件優(yōu)化的方向,因?yàn)?HTTPS 是屬于計(jì)算密集型,應(yīng)該選擇計(jì)算力更強(qiáng)的 CPU,而且最好選擇支持 AES-NI 特性的 CPU,這個(gè)特性可以在硬件級(jí)別優(yōu)化 AES 對(duì)稱加密算法,加快應(yīng)用數(shù)據(jù)的加解密。對(duì)于軟件優(yōu)化的方向,如果可以,把軟件升級(jí)成較新的版本,比如將 Linux 內(nèi)核 2.X 升級(jí)成 4.X,將 openssl 1.0.1 升級(jí)到 1.1.1,因?yàn)樾掳姹镜能浖粌H會(huì)提供新的特性,而且還會(huì)修復(fù)老版本的問題。對(duì)于協(xié)議優(yōu)化的方向:密鑰交換算法應(yīng)該選擇 ECDHE 算法,而不用 RSA 算法,因?yàn)?ECDHE 算法具備前向安全性,而且客戶端可以在第三次握手之后,就發(fā)送加密應(yīng)用數(shù)據(jù),節(jié)省了 1 RTT。將 TSL1.2 升級(jí) TSL1.3,因?yàn)?TSL1.3 的握手過程只需要 1 RTT,而且安全性更強(qiáng)。對(duì)于證書優(yōu)化的方向:服務(wù)器應(yīng)該選用 ECDSA 證書,而非 RSA 證書,因?yàn)樵谙嗤踩?jí)別下,ECC 的密鑰長度比 RSA 短很多,這樣可以提高證書傳輸?shù)男?;服?wù)器應(yīng)該開啟 OCSP Stapling 功能,由服務(wù)器預(yù)先獲得 OCSP 的響應(yīng),并把響應(yīng)結(jié)果緩存起來,這樣 TLS 握手的時(shí)候就不用再訪問 CA 服務(wù)器,減少了網(wǎng)絡(luò)通信的開銷,提高了證書驗(yàn)證的效率;對(duì)于重連 HTTPS 時(shí),我們可以使用一些技術(shù)讓客戶端和服務(wù)端使用上一次 HTTPS 連接使用的會(huì)話密鑰,直接恢復(fù)會(huì)話,而不用再重新走完整的 TLS 握手過程。常見的會(huì)話重用技術(shù)有 Session ID 和 Session Ticket,用了會(huì)話重用技術(shù),當(dāng)再次重連 HTTPS 時(shí),只需要 1 RTT 就可以恢復(fù)會(huì)話。對(duì)于 TLS1.3 使用 Pre-shared Key 會(huì)話重用技術(shù),只需要 0 RTT 就可以恢復(fù)會(huì)話。這些會(huì)話重用技術(shù)雖然好用,但是存在一定的安全風(fēng)險(xiǎn),它們不僅不具備前向安全,而且有重放攻擊的風(fēng)險(xiǎn),所以應(yīng)當(dāng)對(duì)會(huì)話密鑰設(shè)定一個(gè)合理的過期時(shí)間。

>> HTTP/1.1 報(bào)文中 Header 部分存在的問題:含很多固定的字段,比如Cookie、User Agent、Accept 等,這些字段加起來也高達(dá)幾百字節(jié)甚至上千字節(jié),所以有必要壓縮;大量的請(qǐng)求和響應(yīng)的報(bào)文里有很多字段值都是重復(fù)的,這樣會(huì)使得大量帶寬被這些冗余的數(shù)據(jù)占用了,所以有必須要避免重復(fù)性;字段是 ASCII 編碼的,雖然易于人類觀察,但效率低,所以有必要改成二進(jìn)制編碼;

>> HTTP/2 沒使用常見的 gzip 壓縮方式來壓縮頭部,而是開發(fā)了 HPACK 算法,HPACK 算法主要包含三個(gè)組成部分:靜態(tài)字典;動(dòng)態(tài)字典;Huffman 編碼(壓縮算法);客戶端和服務(wù)器兩端都會(huì)建立和維護(hù)「字典」,用長度較小的索引號(hào)表示重復(fù)的字符串,再用 Huffman 編碼壓縮數(shù)據(jù),可達(dá)到 50%~90% 的高壓縮率。靜態(tài)表編碼HTTP/2 為高頻出現(xiàn)在頭部的字符串和字段建立了一張靜態(tài)表,它是寫入到 HTTP/2 框架里的,不會(huì)變化的,靜態(tài)表里共有 61 組,如下圖

>> [插圖]

>> 根據(jù) RFC7541 規(guī)范,如果頭部字段屬于靜態(tài)表范圍,并且 Value 是變化,那么它的 HTTP/2 頭部前 2 位固定為 01,所以整個(gè)頭部格式如下圖:[插圖]HTTP/2 頭部由于基于二進(jìn)制編碼,就不需要冒號(hào)空格和末尾的\r\n作為分隔符,于是改用表示字符串長度(Value Length)來分割 Index 和 Value。

>> 使得動(dòng)態(tài)表生效有一個(gè)前提:必須同一個(gè)連接上,重復(fù)傳輸完全相同的 HTTP 頭部

>> [插圖]

>> 幀頭(Fream Header)很小,只有 9 個(gè)字節(jié),幀開頭的前 3 個(gè)字節(jié)表示幀數(shù)據(jù)(Fream Playload)的長度。幀長度后面的一個(gè)字節(jié)是表示幀的類型,HTTP/2 總共定義了 10 種類型的幀,一般分為數(shù)據(jù)幀和控制幀兩類,如下表格:[插圖]

>>? HTTP/2 實(shí)現(xiàn) 100 個(gè)并發(fā) Stream 時(shí),只需要建立一次 TCP 連接,而 HTTP/1.1 需要建立 100 個(gè) TCP 連接,每個(gè) TCP 連接都要經(jīng)過TCP 握手、慢啟動(dòng)以及 TLS 握手過程,這些都是很耗時(shí)的。

>> HTTP/2 協(xié)議其實(shí)還有很多內(nèi)容,比如流控制、流狀態(tài)、依賴關(guān)系等等。這次主要介紹了關(guān)于 HTTP/2 是如何提示性能的幾個(gè)方向,它相比 HTTP/1 大大提高了傳輸效率、吞吐能力。第一點(diǎn),對(duì)于常見的 HTTP 頭部通過靜態(tài)表和 Huffman 編碼的方式,將體積壓縮了近一半,而且針對(duì)后續(xù)的請(qǐng)求頭部,還可以建立動(dòng)態(tài)表,將體積壓縮近 90%,大大提高了編碼效率,同時(shí)節(jié)約了帶寬資源。不過,動(dòng)態(tài)表并非可以無限增大, 因?yàn)閯?dòng)態(tài)表是會(huì)占用內(nèi)存的,動(dòng)態(tài)表越大,內(nèi)存也越大,容易影響服務(wù)器總體的并發(fā)能力,因此服務(wù)器需要限制 HTTP/2 連接時(shí)長或者請(qǐng)求次數(shù)。第二點(diǎn),HTTP/2 實(shí)現(xiàn)了 Stream 并發(fā),多個(gè) Stream 只需復(fù)用 1 個(gè) TCP 連接,節(jié)約了 TCP 和 TLS 握手時(shí)間,以及減少了 TCP 慢啟動(dòng)階段對(duì)流量的影響。不同的 Stream ID 才可以并發(fā),即時(shí)亂序發(fā)送幀也沒問題,但是同一個(gè) Stream 里的幀必須嚴(yán)格有序。另外,可以根據(jù)資源的渲染順序來設(shè)置 Stream 的優(yōu)先級(jí),從而提高用戶體驗(yàn)。第三點(diǎn),服務(wù)器支持主動(dòng)推送資源,大大提升了消息的傳輸性能,服務(wù)器推送資源時(shí),會(huì)先發(fā)送 PUSH_PROMISE 幀,告訴客戶端接下來在哪個(gè) Stream 發(fā)送資源,然后用偶數(shù)號(hào) Stream 發(fā)送資源給客戶端。HTTP/2 通過 Stream 的并發(fā)能力,解決了 HTTP/1 隊(duì)頭阻塞的問題,看似很完美了,但是 HTTP/2 還是存在“隊(duì)頭阻塞”的問題,只不過問題不是在 HTTP 這一層面,而是在 TCP 這一層。HTTP/2 是基于 TCP 協(xié)議來傳輸數(shù)據(jù)的,TCP 是字節(jié)流協(xié)議,TCP 層必須保證收到的字節(jié)數(shù)據(jù)是完整且連續(xù)的,這樣內(nèi)核才會(huì)將緩沖區(qū)里的數(shù)據(jù)返回給 HTTP 應(yīng)用,那么當(dāng)「前 1 個(gè)字節(jié)數(shù)據(jù)」沒有到達(dá)時(shí),后收到的字節(jié)數(shù)據(jù)只能存放在內(nèi)核緩沖區(qū)里,只有等到這 1 個(gè)字節(jié)數(shù)據(jù)到達(dá)時(shí),HTTP/2 應(yīng)用層才能從內(nèi)核中拿到數(shù)據(jù),這就是 HTTP/2 隊(duì)頭阻塞問題。有沒有什么解決方案呢?既然是 TCP 協(xié)議自身的問題,那干脆放棄 TCP 協(xié)議,轉(zhuǎn)而使用 UDP 協(xié)議作為傳輸層協(xié)議,這個(gè)大膽的決定, HTTP/3 協(xié)議做了!

>> [插圖]

>> HTTP/2 多個(gè)請(qǐng)求是跑在一個(gè) TCP 連接中的,那么當(dāng) TCP 丟包時(shí),整個(gè) TCP 都要等待重傳,那么就會(huì)阻塞該 TCP 連接中的所有請(qǐng)求。

>> QUIC 內(nèi)部包含了 TLS,它在自己的幀會(huì)攜帶 TLS 里的“記錄”,再加上 QUIC 使用的是 TLS1.3,因此僅需 1 個(gè) RTT 就可以「同時(shí)」完成建立連接與密鑰協(xié)商,甚至在第二次連接的時(shí)候,應(yīng)用數(shù)據(jù)包可以和 QUIC 握手信息(連接信息 + TLS 信息)一起發(fā)送,達(dá)到 0-RTT 的效果。

>> 動(dòng)態(tài)表是具有時(shí)序性的,如果首次出現(xiàn)的請(qǐng)求發(fā)生了丟包,后續(xù)的收到請(qǐng)求,對(duì)方就無法解碼出 HPACK 頭部,因?yàn)閷?duì)方還沒建立好動(dòng)態(tài)表,因此后續(xù)的請(qǐng)求解碼會(huì)阻塞到首次請(qǐng)求中丟失的數(shù)據(jù)包重傳過來。

>> HTTP/2 雖然具有多個(gè)流并發(fā)傳輸?shù)哪芰?,但是傳輸層?TCP 協(xié)議,于是存在以下缺陷:隊(duì)頭阻塞,HTTP/2 多個(gè)請(qǐng)求跑在一個(gè) TCP 連接中,如果序列號(hào)較低的 TCP 段在網(wǎng)絡(luò)傳輸中丟失了,即使序列號(hào)較高的 TCP 段已經(jīng)被接收了,應(yīng)用層也無法從內(nèi)核中讀取到這部分?jǐn)?shù)據(jù),從 HTTP 視角看,就是多個(gè)請(qǐng)求被阻塞了;TCP 和 TLS 握手時(shí)延,TCL 三次握手和 TLS 四次握手,共有 3-RTT 的時(shí)延;連接遷移需要重新連接,移動(dòng)設(shè)備從 4G 網(wǎng)絡(luò)環(huán)境切換到 WIFI 時(shí),由于 TCP 是基于四元組來確認(rèn)一條 TCP 連接的,那么網(wǎng)絡(luò)環(huán)境變化后,就會(huì)導(dǎo)致 IP 地址或端口變化,于是 TCP 只能斷開連接,然后再重新建立連接

>> ,

>> 切換網(wǎng)絡(luò)環(huán)境的成本高;

>> HTTP/3 就將傳輸層從 TCP 替換成了 UDP,并在 UDP 協(xié)議上開發(fā)了 QUIC 協(xié)議,來保證數(shù)據(jù)的可靠傳輸。QUIC 協(xié)議的特點(diǎn):無隊(duì)頭阻塞,QUIC 連接上的多個(gè) Stream 之間并沒有依賴,都是獨(dú)立的,也不會(huì)有底層協(xié)議限制,某個(gè)流發(fā)生丟包了,只會(huì)影響該流,其他流不受影響;建立連接速度快,因?yàn)?QUIC 內(nèi)部包含 TLS1.3,因此僅需 1 個(gè) RTT 就可以「同時(shí)」完成建立連接與 TLS 密鑰協(xié)商,甚至在第二次連接的時(shí)候,應(yīng)用數(shù)據(jù)包可以和 QUIC 握手信息(連接信息 + TLS 信息)一起發(fā)送,達(dá)到 0-RTT 的效果。連接遷移,QUIC 協(xié)議沒有用四元組

>> 的方式來“綁定”連接,而是通過「連接 ID 」來標(biāo)記通信的兩個(gè)端點(diǎn),客戶端和服務(wù)器可以各自選擇一組 ID 來標(biāo)記自己,因此即使移動(dòng)設(shè)備的網(wǎng)絡(luò)變化后,導(dǎo)致 IP 地址變化了,只要仍保有上下文信息(比如連接 ID、TLS 密鑰等),就可以“無縫”地復(fù)用原連接,消除重連的成本;另外 HTTP/3 的 QPACK 通過兩個(gè)特殊的單向流來同步雙方的動(dòng)態(tài)表,解決了 HTTP/2 的 HPACK 隊(duì)頭阻塞問題。

三、TCP 篇

>> 第三次握手是可以攜帶數(shù)據(jù)的,前兩次握手是不可以攜帶數(shù)據(jù)的

>> 如何在 Linux 系統(tǒng)中查看 TCP 狀態(tài)?TCP 的連接狀態(tài)查看,在 Linux 可以通過 netstat -napt 命令查看。[插圖]

>> TCP 使用三次握手建立連接的最主要原因是防止歷史連接初始化了連接。

>> TCP 建立連接時(shí),通過三次握手能防止歷史連接的建立,能減少雙方不必要的資源開銷,能幫助雙方同步初始化序列號(hào)。序列號(hào)能夠保證數(shù)據(jù)包不重復(fù)、不丟棄和按序傳輸。不使用「兩次握手」和「四次握手」的原因:「兩次握手」:無法防止歷史連接的建立,會(huì)造成雙方資源的浪費(fèi),也無法可靠的同步雙方序列號(hào);「四次握手」:三次握手就已經(jīng)理論上最少可靠連接建立,所以不需要使用更多的通信次數(shù)。為什么客戶端和服務(wù)端的初始序列號(hào) ISN 是不相同的?如果一個(gè)已經(jīng)失效的連接被重用了,但是該舊連接的歷史報(bào)文還殘留在網(wǎng)絡(luò)中,如果序列號(hào)相同,那么就無法

>> 分辨出該報(bào)文是不是歷史報(bào)文,如果歷史報(bào)文被新的連接接收了,則會(huì)產(chǎn)生數(shù)據(jù)錯(cuò)亂。所以,每次建立連接前重新初始化一個(gè)序列號(hào)主要是為了通信雙方能夠根據(jù)序號(hào)將不屬于本連接的報(bào)文段丟棄。另一方面是為了安全性,防止黑客偽造的相同序列號(hào)的 TCP 報(bào)文被對(duì)方接收。

>> 初始序列號(hào) ISN 是如何隨機(jī)產(chǎn)生的?起始 ISN 是基于時(shí)鐘的,每 4 毫秒 + 1,轉(zhuǎn)一圈要 4.55 個(gè)小時(shí)。RFC1948 中提出了一個(gè)較好的初始化序列號(hào) ISN 隨機(jī)生成算法。ISN = M + F (localhost, localport, remotehost, remoteport)M 是一個(gè)計(jì)時(shí)器,這個(gè)計(jì)時(shí)器每隔 4 毫秒加 1。F 是一個(gè) Hash 算法,根據(jù)源 IP、目的 IP、源端口、目的端口生成一個(gè)隨機(jī)數(shù)值。要保證 Hash 算法不能被外部輕易推算得出,用 MD5 算法是一個(gè)比較好的選擇。

>> [插圖]

>> 為什么 TIME_WAIT 等待的時(shí)間是 2MSL?MSL 是 Maximum Segment Lifetime,報(bào)文最大生存時(shí)間,它是任何報(bào)文在網(wǎng)絡(luò)上存在的最長時(shí)間,超過這個(gè)時(shí)間報(bào)文將被丟棄。因?yàn)?TCP 報(bào)文基于是 IP 協(xié)議的,而 IP 頭中有一個(gè) TTL 字段,是 IP 數(shù)據(jù)報(bào)可以經(jīng)過的最大路由數(shù),每經(jīng)過一個(gè)處理他的路由器此值就減 1,當(dāng)此值為 0 則數(shù)據(jù)報(bào)將被丟棄,同時(shí)發(fā)送 ICMP 報(bào)文通知源主機(jī)。MSL 與 TTL 的區(qū)別: MSL 的單位是時(shí)間,而 TTL 是經(jīng)過路由跳數(shù)。所以 MSL 應(yīng)該要大于等于 TTL 消耗為 0 的時(shí)間,以確保報(bào)文已被自然消亡。TIME_WAIT 等待 2 倍的 MSL,比較合理的解釋是: 網(wǎng)絡(luò)中可能存在來自發(fā)送方的數(shù)據(jù)包,當(dāng)這些發(fā)送方的數(shù)據(jù)包被接收方處理后又會(huì)向?qū)Ψ桨l(fā)送響應(yīng),所以一來一回需要等待 2 倍的時(shí)間。

>> 為什么需要 TIME_WAIT 狀態(tài)? 主動(dòng)發(fā)起關(guān)閉連接的一方,才會(huì)有 TIME-WAIT 狀態(tài)。需要 TIME-WAIT 狀態(tài),主要是兩個(gè)原因:防止具有相同「四元組」的「舊」數(shù)據(jù)包被收到;保證「被動(dòng)關(guān)閉連接」的一方能被正確的關(guān)閉,即保證最后的 ACK 能讓被動(dòng)關(guān)閉方接收,從而幫助其正常關(guān)閉;原因一:防止舊連接的數(shù)據(jù)包假設(shè) TIME-WAIT 沒有等待時(shí)間或時(shí)間過短,被延遲的數(shù)據(jù)包抵達(dá)后會(huì)發(fā)生什么呢

>> ?

>> [插圖]

>> 經(jīng)過 2MSL 這個(gè)時(shí)間,足以讓兩個(gè)方向上的數(shù)據(jù)包都被丟棄,使得原來連接的數(shù)據(jù)包在網(wǎng)絡(luò)中都自然消失,再出現(xiàn)的數(shù)據(jù)包一定都是新建立連接所產(chǎn)生的。

>> 等待足夠的時(shí)間以確保最后的 ACK 能讓被動(dòng)關(guān)閉方接收,從而幫助其正常關(guān)閉。

>> 假設(shè) TIME-WAIT 沒有等待時(shí)間或時(shí)

>> 間過短,斷開連接會(huì)造成什么問題呢?[插圖]

>> 如果已經(jīng)建立了連接,但是客戶端突然出現(xiàn)故障了怎么辦?TCP 有一個(gè)機(jī)制是?;顧C(jī)制。這個(gè)機(jī)制的原理是這樣的:定義一個(gè)時(shí)間段,在這個(gè)時(shí)間段內(nèi),如果沒有任何連接相關(guān)的活動(dòng),TCP ?;顧C(jī)制會(huì)開始作用,每隔一個(gè)時(shí)間間隔,發(fā)送一個(gè)探測報(bào)文,該探測報(bào)文包含的數(shù)據(jù)非常少,如果連續(xù)幾個(gè)探測報(bào)文都沒有得到響應(yīng),則認(rèn)為當(dāng)前的 TCP 連接已經(jīng)死亡,系統(tǒng)內(nèi)核將錯(cuò)誤信息通知給上層應(yīng)用程序。

>> 如果一個(gè)大的 TCP 報(bào)文是被 MTU 分片,那么只有「第一個(gè)分片」才具有 TCP 頭部,后面的分片則沒有 TCP 頭部,接收方 IP 層只有重組了這些分片,才會(huì)認(rèn)為是一個(gè) TCP 報(bào)文,那么丟失了其中一個(gè)分片,接收方 IP 層就不會(huì)把 TCP 報(bào)文丟給 TCP 層,那么就會(huì)等待對(duì)方超時(shí)重傳這一整個(gè) TCP 報(bào)文。如果一個(gè)大的 TCP 報(bào)文被 MSS 分片,那么所有「分片都具有 TCP 頭部」,因?yàn)槊總€(gè) MSS 分片的是具有 TCP 頭部的TCP報(bào)文,那么其中一個(gè) MSS 分片丟失,就只需要重傳這一個(gè)分片就可以。

>> 實(shí)際上「報(bào)文往返 RTT 的值」是經(jīng)常變化的,因?yàn)槲覀兊木W(wǎng)絡(luò)也是時(shí)常變化的。也就因?yàn)椤笀?bào)文往返 RTT 的值」 是經(jīng)常波動(dòng)變化的,所以「超時(shí)重傳時(shí)間 RTO 的值」應(yīng)該是一個(gè)動(dòng)態(tài)變化的值。

>> 每當(dāng)遇到一次超時(shí)重傳的時(shí)候,都會(huì)將下一次超時(shí)時(shí)間間隔設(shè)為先前值的兩倍。兩次超時(shí),就說明網(wǎng)絡(luò)環(huán)境差,不宜頻繁反復(fù)發(fā)送。

>> [插圖]

>> ,窗口大小就是指無需等待確認(rèn)應(yīng)答,而可以繼續(xù)發(fā)送數(shù)據(jù)的最大值

>> 接收窗口和發(fā)送窗口的大小是相等的嗎?

并不是完全相等,接收窗口的大小是約等于發(fā)送窗口的大小的。

因?yàn)榛瑒?dòng)窗口并不是一成不變的。比如,當(dāng)接收方的應(yīng)用進(jìn)程讀取數(shù)據(jù)的速度非??斓脑?,這樣的話接收窗口可以很快的就空缺出來。那么新的接收窗口大小,是通過 TCP 報(bào)文中的 Windows 字段來告訴發(fā)送方。那么這個(gè)傳輸過程是存在時(shí)延的,所以接收窗口和發(fā)送窗口是約等于的關(guān)系。

流量控制

發(fā)送方不能無腦的發(fā)數(shù)據(jù)給接收方,要考慮接收方處理能力。

如果一直無腦的發(fā)數(shù)據(jù)給對(duì)方,但對(duì)方處理不過來,那么就會(huì)導(dǎo)致觸發(fā)重發(fā)機(jī)制,從而導(dǎo)致網(wǎng)絡(luò)流量的無端的浪費(fèi)。

為了解決這種現(xiàn)象發(fā)生,TCP 提供一種機(jī)制可以讓「發(fā)送方」根據(jù)「接收方」的實(shí)際接收能力控制發(fā)送的數(shù)據(jù)量,這就是所謂的流量控制。

>> 直到工作后,認(rèn)識(shí)了兩大分析網(wǎng)絡(luò)的利器:tcpdump 和 Wireshark,這兩大利器把我們“看不見”的數(shù)據(jù)包,呈現(xiàn)在我們眼前,一目了然。

唉,當(dāng)初大學(xué)學(xué)習(xí)計(jì)網(wǎng)的時(shí)候,要是能知道這兩個(gè)工具,就不會(huì)學(xué)的一臉懵逼。

tcpdump 和 Wireshark 有什么區(qū)別?

tcpdump 和 Wireshark 就是最常用的網(wǎng)絡(luò)抓包和分析工具,更是分析網(wǎng)絡(luò)性能必不可少的利器。

tcpdump 僅支持命令行格式使用,常用在 Linux 服務(wù)器中抓取和分析網(wǎng)絡(luò)包。

Wireshark 除了可以抓包外,還提供了可視化分析網(wǎng)絡(luò)包的圖形頁面。

所以,這兩者實(shí)際上是搭配使用的,先用 tcpdump 命令在 Linux 服務(wù)器上抓包,接著把抓包的文件拖出到 Windows 電腦后,用 Wireshark 可視化分析。

>> [插圖]

四、IP 篇

>> 環(huán)回地址是在同一臺(tái)計(jì)算機(jī)上的程序之間進(jìn)行網(wǎng)絡(luò)通信時(shí)所使用的一個(gè)默認(rèn)地址。計(jì)算機(jī)使用一個(gè)特殊的 IP 地址 127.0.0.1 作為環(huán)回地址。與該地址具有相同意義的是一個(gè)叫做 localhost 的主機(jī)名。使用這個(gè) IP 或主機(jī)名時(shí),數(shù)據(jù)包不會(huì)流向網(wǎng)絡(luò)。

>> 域名解析的工作流程瀏覽器首先看一下自己的緩存里有沒有,如果沒有就向操作系統(tǒng)的緩存要,還沒有就檢查本機(jī)域名解析文件 hosts,如果還是沒有,就會(huì) DNS 服務(wù)器進(jìn)行查詢,查詢的過程如下:客戶端首先會(huì)發(fā)出一個(gè) DNS 請(qǐng)求,問 www.server.com 的 IP 是啥,并發(fā)給本地 DNS 服務(wù)器(也就是客戶端的 TCP/IP 設(shè)置中填寫的 DNS 服務(wù)器地址)。

>> 本地域名服務(wù)器收到客戶端的請(qǐng)求后,如果緩存里的表格能找到 www.server.com,則它直接返回 IP 地址。如果沒有,本地 DNS 會(huì)去問它的根域名服務(wù)器:“老大, 能告訴我 www.server.com 的 IP 地址嗎?” 根域名服務(wù)器是最高層次的,它不直接用于域名解析,但能指明一條道路。

>> 根 DNS 收到來自本地 DNS 的請(qǐng)求后,發(fā)現(xiàn)后置是 .com,說:“www.server.com 這個(gè)域名歸 .com 區(qū)域管理”,我給你 .com 頂級(jí)域名服務(wù)器地址給你,你去問問它吧?!北镜?DNS 收到頂級(jí)域名服務(wù)器的地址后,發(fā)起請(qǐng)求問“老二, 你能告訴我 www.server.com 的 IP 地址嗎?”頂級(jí)域名服務(wù)器說:“我給你負(fù)責(zé) www.server.com 區(qū)域的權(quán)威 DNS 服務(wù)器的地址,你去問它應(yīng)該能問到”。

>> 本地 DNS 于是轉(zhuǎn)向問權(quán)威 DNS 服務(wù)器:“老三,www.server.com對(duì)應(yīng)的IP是啥呀?” server.com 的權(quán)威 DNS 服務(wù)器,它是域名解析結(jié)果的原出處。為啥叫權(quán)威呢?就是我的域名我做主。

>> 權(quán)威 DNS 服務(wù)器查詢后將對(duì)應(yīng)的 IP 地址 X.X.X.X 告訴本地 DNS。本地 DNS 再將 IP 地址返回客戶端,客戶端和目標(biāo)建立連接。至此,我們完成了 DNS 的解析過程?,F(xiàn)在總結(jié)一下,整個(gè)過程我畫成了一個(gè)圖。[插圖]

>> [插圖]

>> 主機(jī)會(huì)通過廣播發(fā)送 ARP 請(qǐng)求,這個(gè)包中包含了想要知道的 MAC 地址的主機(jī) IP 地址。當(dāng)同個(gè)鏈路中的所有設(shè)備收到 ARP 請(qǐng)求時(shí),會(huì)去拆開 ARP 請(qǐng)求包里的內(nèi)容,如果 ARP 請(qǐng)求包中的目標(biāo) IP 地址與自己的 IP 地址一致,那么這個(gè)設(shè)備就將自己的 MAC 地址塞入 ARP 響應(yīng)包返回給主機(jī)。

>> 操作系統(tǒng)通常會(huì)把第一次通過 ARP 獲取的 MAC 地址緩存起來,以便下次直接從緩存中找到對(duì)應(yīng) IP 地址的 MAC 地址。不過,MAC 地址的緩存是有一定期限的,超過這個(gè)期限,緩存的內(nèi)容將被清除。

>> [插圖]

>> ICMP 主要的功能包括:確認(rèn) IP 包是否成功送達(dá)目標(biāo)地址、報(bào)告發(fā)送過程中 IP 包被廢棄的原因和改善網(wǎng)絡(luò)設(shè)置等。

>> [插圖]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容