前端備戰秋招之計算機網路
文章內容較長,希望閱讀的同學能夠細品,如內容有差錯,還請評論區斧正
個人部落格上檢視原文
常見協議的埠
OSI體系結構
自低向上(7層結構)
- 物理層
- 資料鏈路層
- 網路層
- 傳輸層
- 會話層
- 表現層
- 應用層
TODO:貼生動形象圖
TCP/IP
自底向上(4層)
- 網路介面層
- 網路IP層
- 運輸層
- 應用層
TODO:貼生動形象圖
五層體協結構
自底向上
- 物理層
- 資料鏈路層
- 網路層
- 運輸層
- 應用層
TODO:貼生動形象圖
網際層IP協議
- ARP:地址解析協議--從網路層使用的 IP 地址,解析出在資料鏈路層使用的硬體地址
- ICMP:網際控制報文協議--用於在IP主機、路由器之間傳遞控制訊息
- ICMP 允許主機或路由器報告差錯情況和提供有關異常情況的報告
- ICMP 屬於IP 層的協議
- PING 使用了 ICMP 回送請求與回送回答報文
- IGMP:網際組管理協議--
IP地址分類
類別 | 構成(x+網路號+主機號) | 範圍 | 用途 |
---|---|---|---|
A | 0 +7+24 |
1.0.0.1---126.255.255.254 | |
B | 10 +14+16 |
128.0.0.0---191.255.0.0 | |
C | 110 +21+8 |
192.0.0.0--- 223.255.255.0 | |
D | 1110 + 28(多播) |
多播地址 | |
E | 11110 +留用 |
保留今後使用 |
通訊型別
- 單播:從一臺主機向另一臺主機傳送資料包的過程
- 組播:從一臺主機向選定的一組主機傳送資料包的過程
- 廣播:從一臺主機向該網路中的所有主機傳送資料包的過程
- A類、B類與C類IP地址中主機號全1的地址為直接廣播地址
IP資料包
構成
- 首部
- 前:固定長度20
- 後:有可選欄位,長度可變
- 資料
圖解構成
TODO:想辦法巧妙記住
- 版本:4位--IP協議版本,等於4代表IPV4
- 首部長度:4位--可表示的最大數值15*4=60位元組,因此 IP 的首部長度的最大值是 60 位元組
- 區分服務:8位--用來獲得更好的服務,在一般的情況下都不使用這個欄位
- 總長度:16位--首部和資料之和長度,單位位元組,於是資料包的最大長度為65535位元組 2^16-1
- 總長度必須不超過最大傳送單元
MTU
- 總長度必須不超過最大傳送單元
- 標識:16位--計數器,用來產生IP資料包的標識
- 標誌:3位--目前只有前兩位有意義
- 最低位MF(More Fragment):1--後面還有分片,0--為最後一個分片
- 中間位DF(Don't Fragment):0--才允許分片
- 片偏移:13位--指出:較長的分組在分片後,某片在原分組中的相對位置
- 片偏移以 8 個位元組為偏移單位
- 生存時間:8位--記為TTL(Time To Live),資料包在網路中可通過的路由器數的最大值
- 協議:8位--指出此資料包攜帶的資料使用何種協議
- 以便目的主機的 IP 層將資料部分上交給那個處理過程
- 首部檢驗和:16位--只檢驗資料包的首部,不檢驗資料部分
- 這裡不採用 CRC 檢驗碼而採用簡單的計算方法
- IP 資料包首部檢驗和的計算採用 16 位二進位制反碼求和演算法
- 源地址:32位--4位元組
- 目的地之:32位--4位元組
PING
- PING 用來測試兩個主機之間的連通性
- PING 使用了 ICMP 回送請求與回送回答報文
- PING 是應用層直接使用網路層 ICMP 的例子,它沒有通過運輸層的 TCP 或UDP
運輸層
UDP
使用者資料包協議(User Datagram Protocol)
- 資料單位協議:TCP報文段
特點
- 無連線服務協議
- 傳送資料之前不需要建立連線
- 盡最大努力交付,不提供可靠交付
- 資料包文的搬運工,不保證有序且不丟失的傳遞到對端
- 面向報文的
- 沒有擁塞控制,沒有流量控制演算法
- 支援一對一、一對多、多對一和多對多的互動通訊
- UDP 的首部開銷小,只有 8 個位元組,比 TCP 的 20 個位元組的首部要短
面向無連線
- UDP 是不需要和 TCP 一樣在傳送資料前進行三次握手建立連線,想發資料就可以開始傳送了
- 只是資料包文的搬運工,不會對資料包文進行任何拆分和拼接操作
- 傳送端:應用層將資料傳遞給傳輸層的 UDP 協議,UDP 只會給資料增加一個 UDP 頭,表示用的是 UDP 協議,然後就傳遞給網路層了
- 接收端:網路層將資料傳遞給傳輸層,UDP 只去除 IP 報文頭就傳遞給應用層,不會任何拼接操作
不可靠性
- 不可靠性體現在無連線上
- 通訊不需要建立連線,想發就發
- 收到什麼資料就發生什麼資料,不對資料進行校驗與備份
- 不關心傳送端是否收到了資料
- 沒有擁堵控制會以恆定的速度傳送資料
- 在網路條件不好的情況下會導致丟包
高效
- UDP 的首部開銷小,只有 8 個位元組,比 TCP 的 20 個位元組的首部要少得多
傳輸方式
- 一對多:單播
- 多對多:多播
- 多對一:廣播
適合場景
對當前網路通訊質量要求不高的時候,實時性要求高的地方都可以看到 UDP 的身影,要求網路通訊速度儘量的快,這時就使用UDP
- 網遊
- 直播
- 語音
- 視屏等等
資料包格式
- 源埠--16位
- 目的埠--16位
- 整個資料包文的長度--16位
- 檢驗和--16位該欄位用於發現頭部資訊和資料中的錯誤
總結
- UDP 相比 TCP 簡單的多,不需要建立連線,不需要驗證資料包文,不需要流量控制,只會把想發的資料包文直接傳送給對端
- 雖然 UDP 並沒有 TCP 傳輸來的準確,但是也能在很多實時性要求高的地方有所作為
TCP
傳輸控制協議(Transmission Control Protocol)
- 資料單位協議:UDP報文、使用者資料包
特點
- 面向連線的運輸層協議
- 每一條 TCP 連線只能有兩個端點 (endpoint),每一條 TCP 連線
只能是點對點
的(一對一) - 提供可靠交付的服務
- 提供全雙工通訊
- 面向位元組流
- 但 TCP 傳送的資料單元卻是報文段
- TCP 不提供廣播或多播服務
- 首部的前 20 個位元組是固定的,後面有 4n 位元組是根據需要而增加的選項 (n 是整數)
- 因此 TCP 首部的最小長度是 20 位元組
建立連線三次握手
三報文握手主要是為了防止已失效的連線請求報文段突然又傳送到了,因而產生錯誤。
起初,兩端都為 CLOSED 狀態。在通訊開始前,雙方都會建立 TCB。 伺服器建立完 TCB 後便進入 LISTEN 狀態,此時開始等待客戶端傳送資料
- 第一次握手
- 客戶端傳送的SYN=1(同步序列號seq=x)的包到服務端並變為SYN-SENT(請求連線)狀態,等待服務端響應
- 第二次握手
- 服務端收到客戶端請求後,傳送一個包(SYN=1,ACK=1,seq=y,ack=x+1)給客戶發端,服務端進入SYN_RECEVIED狀態
- 第三次握手
- 客戶端收到服務端響應的包(SYN=1,ACK=1)後,再向服務端傳送確認包(ACK=1,seq=x+1,ack=y+1),傳送完畢,客戶端和服務端都進入ESTABLISHED狀態,完成握手
連線釋放四次揮手
資料傳輸結束後,通訊的雙方都可釋放連線
TCP 是全雙工的,在斷開連線時兩端都需要傳送 FIN 和 ACK
- 第一次揮手
- 客戶端認為資料傳送完成,向服務端傳送連結釋放請求(FIN=1,序號seq=u),等待服務端確認
- 第二次揮手
- 服務端收到請求後,通知應用層要釋放 TCP 連結。然後會發出確認包(ACK =1,seq=V,ACK=u+1),並進入 CLOSE_WAIT 狀態
- 此時表明 客戶端 到 服務端 的連線已經釋放,不再接收 客戶端 發的資料了
- 但是因為 TCP 連線是雙向的,此時處於半關閉狀態服務端 仍舊可以傳送資料給 客戶端
- 服務端如果此時還有沒發完的資料會繼續傳送
- 服務端收到請求後,通知應用層要釋放 TCP 連結。然後會發出確認包(ACK =1,seq=V,ACK=u+1),並進入 CLOSE_WAIT 狀態
- 第三次揮手
- 服務端傳送完畢後向 客戶端 傳送連線釋放請求(FIN=1,ACK=1,seq=w,ack=u+1),然後 服務端 便進入 LAST-ACK 狀態
- 第四次揮手
- 客戶端收到連線釋放報文段後,向服務端傳送確認應答
- 然後 客戶端 進入 TIME-WAIT 狀態
- 該狀態會持續 2MSL(最大段生存期,指報文段在網路中生存的時間,超時會被拋棄) 時間,若該時間段內沒有 B 的重發請求的話,就進入 CLOSED 狀態。當 服務端 收到確認應答後,也便進入 CLOSED 狀態。
首部格式
- 源埠:2位元組
- 目的埠:2位元組
- 埠是運輸層與應用層的服務介面。運輸層的複用和分用功能都要通過埠才能實現
- 序號:4 位元組
- TCP 連線中傳送的資料流中的每一個位元組都編上一個序號
- 序號欄位的值則指的是本報文段所傳送的資料的第一個位元組的序號
- 報文段的序號欄位值=301,而攜帶的資料共有100位元組,則本報文段的資料第一個位元組序號是301,最後一個位元組的序號是400.那麼下一個報文段的資料序號應當是401
- 確認號:4 位元組,是期望收到對方的下一個報文段的資料的第一個位元組的序號
- 若確認號=N 則表示:到序號N-1為止的所有資料都已正確收到
- 如果接收方B收到A傳送過來的報文段,序號=501,資料長度是200位元組,表明B收到了A傳送的到序號700為止的資料。則B傳送給A的確認報文段中把確認號設定為701
- 資料偏移:4位,指出 TCP 報文段的資料起始處距離 TCP 報文段的起始處有多遠
- 單位是4位元組
- 實際上是TCP報文段的首部長度
- 最大TCP報文段首部=60位元組=(2^4-1)*4
- 保留欄位:6 位,保留為今後使用
- 目前應置為 0
- URG:1位,緊急(urgent)
- 當 URG為1 時,表明緊急指標欄位有效,它告訴系統此報文段中有緊急資料,應儘快傳送(相當於高優先順序的資料)
- ACK:1位,確認(acknowledge)
- ACK=1時確認號才有效
- PSH:1位,推送(push)
- PSH = 1 的報文段,就儘快地交付接收應用程式,而不再等到整個快取都填滿了後再向上交付
- RST:1位,復位(reset)
- RST=1,TCP 連線中出現嚴重差錯(如由於主機崩潰或其他原因),必須釋放連線,然後再重新建立運輸連線
- SYN:1位,同步(synchronous)
- SYN = 1 表示這是一個連線請求或連線接受報文
- SYN=1 ACK=0: 連線請求報文段
- SYN=1 ACK=1:連線接收報文段
- SYN = 1 表示這是一個連線請求或連線接受報文
- FIN:1位,終止(finish)
- FIN = 1 表明此報文段的傳送端的資料已傳送完畢,並要求釋放運輸連線
- 視窗欄位:2 位元組-視窗是傳送本報文段的一方的接收視窗,是用來讓對方設定傳送視窗的依據
- 如確認號=701,視窗欄位=1000,則表示告訴對方:從701號開始,我的接收快取還可以接收1000位元組
- 檢驗和:2 位元組,檢驗和欄位檢驗的範圍包括首部和資料這兩部分
- 在計算檢驗和時,要在 TCP 報文段的前面加上 12 位元組的偽首部
- 緊急指標欄位:2位元組,指出在本報文段中緊急資料共有多少個位元組(緊急資料放在本報文段資料的最前面)
- 選項欄位:長度可變
- TCP 最初只規定了一種選項,即最大報文段長度 MSS
- MSS 告訴對方TCP:“我的快取所能接收的報文段的資料欄位的最大長度是 MSS 個位元組。”
- 資料欄位加上 TCP 首部才等於整個的 TCP 報文段
- 所以,MSS是“TCP 報文段長度減去 TCP 首部長度”
- TCP 最初只規定了一種選項,即最大報文段長度 MSS
- 填充欄位:這是為了使整個首部長度是 4 位元組的整數倍
可靠傳輸工作原理
停止等待ARQ
每傳送完一個分組就停止傳送,等待對方的確認。在收到確認後再傳送下一個分組。
連續ARQ
傳送方維持的傳送視窗,它的意義是:位於傳送視窗內的分組都可連續傳送出去,而不需要等待對方的確認。這樣,通道利用率就提高了
連續 ARQ 協議規定,傳送方每收到一個確認,就把傳送視窗向前滑動一個分組的位置。
流量控制
流量控制所要做的就是抑制傳送端傳送資料的速率,以便使接收端來得及接收
利用滑動視窗實現流量控制
擁塞控制
擁塞控制就是防止過多的資料注入到網路中,使網路中的路由器或鏈路不致過載
- TCP 採用基於視窗的方法進行擁塞控制。該方法屬於閉環控制方法。
- TCP傳送方維持一個擁塞視窗 CWND
- 擁塞視窗的大小取決於網路的擁塞程度,並且動態地在變化。
- 傳送端利用擁塞視窗根據網路的擁塞情況調整傳送的資料量。
- 所以,傳送視窗大小不僅取決於接收方公告的接收視窗,還取決於網路的擁塞狀況,所以真正的傳送視窗值為:min(公告視窗值,擁塞視窗值)
擁塞的判斷
- 重傳定時器超時
- 收到三個相同重複的ACK
四種控制演算法
- 慢開始:由小到大逐漸增大擁塞視窗數值
- 擁塞避免:讓擁塞視窗 cwnd 緩慢地增大,即每經過一個往返時間 RTT 就把傳送方的擁塞視窗 cwnd 加 1,而不是加倍,使擁塞視窗 cwnd 按線性規律緩慢增長
- 快重傳:讓傳送方儘早知道發生了個別報文段的丟失
- 傳送方只要一連收到三個重複確認,就知道接收方確實沒有收到報文段,因而應當立即進行重傳
- 快恢復:當傳送端收到連續三個重複的確認時,由於傳送方現在認為網路很可能沒有發生擁塞,因此現在不執行慢開始演算法,而是執行快恢復演算法
適合場景
- HTTP
- FTP
- SMTP
- 檔案傳輸
- 遊戲。。。
TCP與UDP相關問題
1.為什麼 TCP 建立連線需要三次握手,明明兩次就可以建立起連線?
- 防止出現失效的連線請求報文段被服務端接收的情況,從而產生錯誤
- 如果只有1次:客戶端收到請求後,沒收到應答,無法判斷連結是否連線成功
- 如果只有2次:
- 客戶端傳送連線請求後,等待伺服器端的應答。
- 如過客戶端的SYN過了一段時間沒有到達伺服器端,客戶端連結超時,會重新傳送一次連線請求
- 如果重發的這次伺服器端收到了,且應答了客戶端,連線就建立了
- 但是建立後,第一個SYN也到達服務端了,這時服務端會認為這是一個新連線,會再給客戶端傳送一個ACK,這個ACK當然會被客戶端丟棄
- 但是此時伺服器端已經為這個連線分配資源了,而且伺服器端會一直維持著這個資源,會造成浪費
2.三次握手過程中可以攜帶資料麼?
- 第三次可以攜帶
- 客戶端已經處於ESTABLIEISH狀態,已經能夠確認服務端的接收,傳送能力正常,這個時候可以攜帶
- 前兩次不可以
- 一旦有人想攻擊伺服器,只需要在第一次握手中的 SYN 報文中放大量資料,那麼伺服器會消耗更多的時間和記憶體空間去處理這些資料,增大了伺服器被攻擊的風險
3.為什麼 A 要進入 TIME-WAIT 狀態,等待 2MSL 時間後才進入 CLOSED 狀態
MSL -- Maximum Segment Lifetime -- 報文最大生存時間,最長報文壽命
- 為了保證 客戶端 傳送的最後一個 ACK 報文段能夠到達 服務端
- 防止 “已失效的連線請求報文段”出現在本連線中
- 若 客戶端 發完確認應答後直接進入 CLOSED 狀態,如果確認應答因為網路問題一直沒有到達,那麼會造成 服務端 不能正常關閉。
- 如果不等待客戶端直接關閉,當服務端還有資料包要傳送給客戶端時,且還在傳輸的路上,若客戶端的埠此時剛好被新的應用佔用,那麼就接收到了無用資料包,造成資料包混亂
- 2MSL意義:
- 1 個 MSL 確保四次揮手中主動關閉方最後的 ACK 報文最終能達到對端
- 1 個 MSL 確保對端沒有收到 ACK 重傳的 FIN 報文可以到達
- 經過2MSL,可以使本連結持續時間內所產生的所有報文段,都從網路中消失
4.TCP與UDP的區別
-
UDP 協議是面向無連線的:不需要在正式傳遞資料之前先連線起雙方
-
UDP 協議只是資料包文的搬運工:不保證有序且不丟失的傳遞到對端
-
UDP 協議也沒有任何控制流量的演算法
-
UDP 相較於 TCP 更加的輕便
-
UDP 的首部開銷小,只有 8 個位元組,比 TCP 的 20 個位元組的首部要少得多
-
TCP面向連線的
-
基本與UDP反著來
-
建立連線3次握手
-
斷開連線4次揮手
-
通過各種演算法保持保證傳輸的可靠性
HTTP
超文字傳輸協議(HyperText Transfer Protocol)),基於TCP實現的應用層協議
特點
- 請求響應模型:客戶端傳送請求,服務端響應請求
- 無狀態協議:不需要建立持久連結
工作過程
- 地址解析
- 封裝HTTP請求資料包
- 封裝成TCP包,建立TCP連結
- 客戶端傳送請求
- 服務端響應
- 關閉TCP連結
- 保持連結的方案:在請求/響應頭中加入
Connection:keep-alive
就可以保持連結開啟狀態
- 保持連結的方案:在請求/響應頭中加入
請求構成
- 請求行
- 首部
- 實體
響應構成
- 協議/版本號 狀態碼
- 首部
- 實體
請求行
GET /images/logo.gif HTTP/1.1
由請求方法、URL、協議版本組成
請求方法
請求方法分為很多種,最常用的也就是 Get 和 Post 了。雖然請求方法有很多,但是更多的是傳達一個語義,而不是說 Post 能做的事情 Get 就不能做了
- Get:應該只被用於獲取資料
- Post:用於將實體提交到指定的資源,通常導致在伺服器上的狀態變化或副作用.
- Put:求有效載荷替換目標資源的所有當前表示,即更新操作.
- Delete:刪除指定的資源
- Patch:用於對資源應用部分修改
- Head:請求一個與GET請求的響應相同的響應,但沒有響應體.
- Connect:建立一個到由目標資源標識的伺服器的隧道
- Options:描述目標資源的通訊選項
- Trace:沿著到目標資源的路徑執行一個訊息環回測試。
URI
Uniform Resource Identifier
--統一資源識別符號,用於區分網際網路上不同資源
URI
包含 URL
與 URN
URI只能使用ASCII, ASCII 之外的字元不支援顯示,因此,URI 引入了編碼機制,將所有非 ASCII 碼字元和界定符轉為十六進位制位元組值,然後在前面加個%
URL
scheme://host:port/path?query
- scheme:協議,HTTP,HTTPS,FTP
- host:主機名,sugarat.top
- port:埠號,預設80,https預設443
- path:資源路徑
- query:用於查詢的引數
URN
path?query
副作用和冪等
-
副作用:指對伺服器上的資源做改變
- 搜尋是無副作用的,註冊是副作用
-
冪等:指傳送 M 和 N 次請求(兩者不相同且都大於 1)
- 伺服器上資源的狀態一致,比如註冊 10 個和 11 個帳號是不冪等的
- 對文章進行更改 10 次和 11 次是冪等的。因為前者是多了一個賬號(資源),後者只是更新同一個資源。
常見首部
通用首部
欄位 | 作用 |
---|---|
Cache-Control | 控制快取的行為 |
Connection | 瀏覽器想要優先使用的連線型別,比如 keep-alive |
Date | 建立報文時間 |
Pragma | 報文指令 |
Via | 代理伺服器相關資訊 |
Transfer-Encoding | 傳輸編碼方式 |
Upgrade | 要求客戶端升級協議 |
Warning | 在內容中可能存在錯誤 |
請求首部
欄位 | 作用 |
---|---|
Host | 訪問資源所在的主機名 |
Accept | 能正確接收的媒體型別(application/json) |
Accept-Charset | 能正確接收的字符集 |
Accept-Encoding | 能正確接收的編碼格式列表(gzip) |
User-Agent | 傳送請求的客戶端資訊 |
Referer | 瀏覽器所訪問的前一個頁面 |
Accept-Language | 能正確接收的語言列表(zh-CN, zh, en) |
If-Match | 值與請求資源ETag相同才會處理請求 |
If-None-Match | 值與請求資源ETag不相同才會處理請求 |
響應首部
欄位 | 作用 |
---|---|
Age | 資源在代理快取中存在的時間 |
Server | 伺服器名字 |
Content-Length | 告知客戶端資源長度 |
Expires | 告知客戶端資源失效日期 |
Last-Modified | 告知客戶端資源最後一次修改的時間 |
E-tag | 檔案指紋,資源唯一識別符號 |
Location | 客戶端重定向到某個 URL |
Proxy-Authenticate | 向代理伺服器傳送驗證資訊 |
cookie
欄位 | 作用 |
---|---|
Cookie | 請求時攜帶的cookie |
Set-Cookie | 響應時服務端傳回的cookie |
壓縮相關
欄位 | 作用 |
---|---|
Content-Encoding | 傳送端使用的編碼方式 |
Accept-Encoding | 接收端支援的編碼格式 |
狀態碼
1xx協議處理的中間狀態
101
在HTTP升級為WebSocket的時候,如果伺服器同意變更,就會傳送狀態碼 101
2xx成功
200
客戶端的請求被服務端正確處理204
請求成功但響應報文不包含實體的主體部分- 206 範圍請求,客戶端進行了部分請求,服務端返回指定部分的內容
- 205 與204作用一致但要求請求方重置內容
3xx重定向
301
永久性重定向,表示資源已被分配了新的url302
臨時性重定向,表示資源臨時被分配了新的url304
當客戶端擁有可能過期的快取時,會攜帶快取的標識 etag、時間等資訊詢問伺服器快取是否仍可複用,而304是告訴客戶端可以複用快取- 303 資源存在另一個url,服務端要求客戶端使用get請求
- 307 臨時重定向,向新的url傳送同樣的請求
4XX客戶端錯誤
400
請求報文存在語法錯誤401
傳送的請求需要有通過 HTTP 認證的認證資訊403
對請求資源的訪問被伺服器拒絕,資源允許訪問,但請求不滿足條件404
在伺服器上沒有找到請求的資源405
當前的請求方法不被允許415
不支援的媒體型別,檢查Content-Type
5XX 伺服器錯誤
500
伺服器端在收到請求後後,執行相關動作時發生了錯誤502
bad gate無效閘道器- 501 表示伺服器不支援當前請求所需要的某個功能
- 503 表明伺服器暫時處於超負載或正在停機維護,無法處理請求
缺點
- 通訊使用明文,可能被竊聽
- 不驗證通訊方的身份,可能遭遇偽裝
- 無法證明報文的完整性,有可能遭遇篡改
HTTPS
HTTP + 加密 + 認證 + 完整性保護 = HTTPS
- 基於HTTP協議,通過SSL或TLS協議提供加密處理資料、驗證對方身份以及資料完整性保護
- 在HTTP上建立SSL加密層,並對傳輸資料進行加密,是HTTP協議的安全版
特點
通過抓包獲取到的資料不是明文傳輸的
- 內容加密:採用混合加密技術,中間者無法直接檢視明文內容
- 驗證身份:通過證書認證客戶端訪問的是自己的伺服器
- 保護資料完整性:防止傳輸的內容被中間人冒充或者篡改
缺點
- 效能損耗
- 增加延時
- 消耗較多的CPU資源
優化方案
- CDN
- 會話快取
TLS/SSL
TLS是傳輸層加密協議,前身是SSL協議
TLS 協議位於傳輸層之上,應用層之下
HTTPS 還是通過了 HTTP 來傳輸資訊,但是資訊通過 TLS 協議進行了加密
功能實現
利用非對稱加密實現身份認證和金鑰協商,採用對稱加密演算法協商的金鑰對資料加密,基於雜湊函式驗證資訊的完整性
- 雜湊函式 Hash:MD5,SHA,SHA256---完成校驗
- 對稱加密 1-1:AES,DES,RC4---資訊加密
- 非對稱加密 1-N:RSA,ECC,DH---身份驗證祕鑰協商
對稱加密
對稱加密就是兩邊擁有相同的祕鑰,兩邊都知道如何將密文加密解密。
這種加密方式固然很好,但是問題就在於如何讓雙方知道祕鑰。因為傳輸資料都是走的網路,如果將祕鑰通過網路的方式傳遞的話,一旦祕鑰被截獲就沒有加密的意義的。
非對稱加密
有公鑰私鑰之分,公鑰所有人都可以知道,可以將資料用公鑰加密,但是將資料解密必須使用私鑰解密,私鑰只有分發公鑰的一方才知道。
這種加密方式就可以完美解決對稱加密存在的問題。假設現在兩端需要使用對稱加密,那麼在這之前,可以先使用非對稱加密交換祕鑰。
簡單流程如下:首先服務端將公鑰公佈出去,那麼客戶端也就知道公鑰了。接下來客戶端建立一個祕鑰,然後通過公鑰加密併傳送給服務端,服務端接收到密文以後通過私鑰解密出正確的祕鑰,這時候兩端就都知道祕鑰是什麼了。
TLS1.2握手過程
- 客戶端發出請求:
- 一個隨機值(用於生成對話祕鑰)
- 支援的協議
- 支援加密方式
- 支援壓縮的方法
- 服務端收到客戶端的請求,向客戶端發出回應:
- 一個隨機值(用於生成對話祕鑰)
- 確定使用的協議
- 確定使用的加密方式
- 傳送自己的證書(如果需要驗證客戶端證書需要說明)
- 客戶端收到服務端的證書並驗證是否有效,如果證書沒問題,向服務端傳送一個請求:
- 生成一個隨機值(用證書公鑰加密)
- 編碼改變通知(隨後的資訊將使用雙方商定的加密方法和祕鑰傳送)
- 客戶端握手結束通知(前面傳送的所有內容的hash值,用來提供給服務端校驗)
- 服務端最後響應
- 伺服器收到客戶端的第三個隨機數之後(用私鑰解密)結合之前的兩個明文隨機數,計算生成本次會話所用的"會話金鑰"
- 編碼改變通知(隨後的資訊都將用雙方商定的加密方法和金鑰傳送)
- 伺服器握手結束通知(前面傳送的所有內容的hash值,用來提供給客戶端校驗)
通過以上步驟可知,在 TLS 握手階段,兩端使用非對稱加密的方式來通訊,實現身份驗證並協商對稱加密使用的金鑰,但是因為非對稱加密損耗的效能比對稱加密大,所以在正式傳輸資料時,兩端使用對稱加密的方式通訊。不同的節點之間採用的對稱金鑰不同,從而可以保證資訊只能通訊雙方獲取
TLS1.3
TLS1.3 中廢除了非常多的加密演算法,如果私鑰洩露,那麼中間人可以破解所有密文
TLS1.3 在 TLS1.2 的基礎上廢除了大量的演算法,提升了安全性。同時利用會話複用節省了重新生成金鑰的時間,利用 PSK 做到了0-RTT連線
HTTP2
HTTP/2 相比於 HTTP/1,大幅度提高了網頁的效能
在 HTTP/1 中,瀏覽器限制了同一個域名下的請求數量(Chrome 下一般是限制六個連線)
當頁面中需要請求很多資源的時候,隊頭阻塞(Head of line blocking)會導致在達到最大請求數量時,剩餘的資源需要等待其他資源請求完成後才能發起請求
特點
- HTTP/2 中引入了多路複用的技術,這個技術可以只通過一個 TCP 連線就可以傳輸所有的請求資料。多路複用很好的解決了瀏覽器限制同一個域名下的請求數量的問題,同時也間接更容易實現全速傳輸
- 在之前的 HTTP 版本中,我們是通過文字的方式傳輸資料。在 HTTP/2 中引入了新的編碼機制,所有傳輸的資料都會被分割,並採用二進位制格式編碼。
多路複用
在 HTTP/2 中,有兩個非常重要的概念,分別是:
- 幀(frame) 代表最小的資料單位,每個幀會標識出該幀屬於哪個流
- 流(stream) 是多個幀組成的資料流
多路複用,就是在一個 TCP 連線中可以存在多條流。換句話說,也就是可以傳送多個請求,對端可以通過幀中的標識知道屬於哪個請求。
通過這個技術,多個請求共享一個TCP連線,可以避免 HTTP 舊版本中的隊頭阻塞問題,極大的提高傳輸效能
Header 壓縮
在 HTTP/1 中,我們使用文字的形式傳輸 header,在 header 攜帶 cookie 的情況下,可能每次都需要重複傳輸幾百到幾千的位元組。
在 HTTP /2 中,使用了 HPACK 壓縮格式對傳輸的 header 進行編碼,減少了 header 的大小。並在兩端維護了索引表,用於記錄出現過的 header ,後面在傳輸過程中就可以傳輸已經記錄過的 header 的鍵名,對端收到資料後就可以通過鍵名找到對應的值
服務端 Push
在 HTTP/2 中,服務端可以在客戶端某個請求後,主動推送其他資源。
可以想象以下情況,某些資源客戶端是一定會請求的,這時就可以採取服務端 push 的技術,提前給客戶端推送必要的資源,這樣在使用的時候就可以相對減少一點延遲時間。
設定請求優先順序
- 可在新建的流所傳遞HEADERS幀中包含優先順序priority屬性
- 可單獨通過PRIORITY幀專門設定流的優先順序屬性
使用前置條件
- 支援HTTP2的客戶端與服務端
- 域名必須支援HTPPS協議(基於TLS/1.2或以上版本的加密連線)
- 伺服器的openssl版本必須大於1.0.2
可通過Nginx搭建HTTP2伺服器
HTTP3
HTTP/2 使用了多路複用
一般來說同一域名下只需要使用一個 TCP 連線。當這個連線中出現了丟包的情況,那就會導致 HTTP/2 的表現情況反倒不如 HTTP/1 了
- 出現丟包的情況下,整個 TCP 都要開始等待重傳,也就導致了後面的所有資料都被阻塞了
- 對於 HTTP/1 來說,可以開啟多個 TCP 連線,出現這種情況反到只會影響其中一個連線,剩餘的 TCP 連線還可以正常傳輸資料
基於這個原因,Google 就更起爐灶搞了一個基於 UDP 協議的 QUIC 協議,並且使用在了 HTTP/3 上
QUIC
QUIC 基於 UDP,在原本的基礎上新增了很多功能
- 多路複用
- 0-RTT
- 使用TLS1.3加密
- 流量控制
- 有序交付
- 重傳
- 。。。
一種全新的基於UDP的web開發協議。可以用一個公式大致概括:
TCP + TLS + HTTP2 = UDP + QUIC + HTTP2’s API
QUIC協議雖然是基於UDP,但它不但具有TCP的可靠性、擁塞控制、流量控制等,且在TCP協議的基礎上做了一些改進,比如避免了隊首阻塞;
另外,QUIC協議具有TLS的安全傳輸特性,實現了TLS的保密功能,同時又使用更少的RTT建立安全的會話。
多路複用
無隊頭阻塞的多路複用
QUIC 原生實現了這個功能,並且傳輸的單個資料流可以保證有序交付且不會影響其他的資料流,這樣的技術就解決了之前 TCP 存在的問題
QUIC 在移動端的表現也會比 TCP 好:
- 因為 TCP 是基於 IP 和埠去識別連線的,這種方式在多變的移動端網路環境下是很脆弱的
- QUIC 是通過 ID 的方式去識別一個連線,不管你網路環境如何變化,只要 ID 不變,就能迅速重連上
0-RTT
與其他協議比較
- TCP建立連結需要三次握手,每次連線需要額外的RTT
- HTTPS加入了TLS還需要額外的RTT
0-RTT情況
通過使用類似 TCP 快速開啟的技術,快取當前會話的上下文,在下次恢復會話的時候,只需要將之前的快取傳遞給服務端驗證通過就可以進行傳輸了
1-RTT情況
新的QUIC連線至少需要1 RTT才能完成握手
糾錯機制
假如說這次我要傳送三個包,那麼協議會算出這三個包的異或值並單獨發出一個校驗包,也就是總共發出了四個包
當出現其中的非校驗包丟包的情況時,可以通過另外三個包計算出丟失的資料包的內容。
當然這種技術只能使用在丟失一個包的情況下,如果出現丟失多個包就不能使用糾錯機制了,只能使用重傳的方式了
結構對比圖
總結HTTP/2|3
- HTTP/2 通過多路複用、二進位制流、Header 壓縮等等技術,極大地提高了效能,但是還是存在著一定的問題的
- QUIC 基於 UDP 實現,是 HTTP/3 中的底層支撐協議,該協議基於 UDP,又取了 TCP 中的精華,實現了即快又可靠的協議,但目前相容性並不好
HTTP相關問題
1.POST和GET區別
使用場景上區分
- GET多用於無副作用,冪等
- POST多用於有副作用,不冪等
技術上
- GET會快取,POST不會快取
- GET請求引數會出現在url中,post相對安全一點
- URL有長度限制,會影響GET請求(瀏覽器規定)
- POST支援更多的編碼型別,且不對資料做限制
- GET只能進行URL編碼,只能接受ASCII字元
2.HTTP與HTTPS區別
- 安全:HTTP明文傳輸資料,HTTPS是在HTTP上建立SSL/TLS加密層,並對傳輸資料進行加密,更加安全
- 埠:http使用80埠,https使用443
- 速度:HTTP頁面響應速度更快
- HTTP只需建立TCP連線,傳送3個包
- HTTPS還需要經歷TLS握手9個包需要,一共12個
3.HTTP1.1 如何解決 HTTP 的隊頭阻塞問題?
- 域名分片:使用多個指向同一伺服器的二級域名
- 併發連線:也就是同時對一個域名發起多個長連線,用數量來解決質量的問題
- 瀏覽器一般會有限制
4.如果響應頭Content-Length=0那麼是發出來被擷取了還是沒發出來
結論:發出來被擷取了
- Content-Length比實際的長度大, 服務端/客戶端讀取到訊息結尾後, 會等待下一個位元組,無響應直到超時
- Content-Length < 實際長度:首次請求的訊息會被擷取
- Content-Length如果存在且生效, 必須是正確的, 否則會發生異常
- 如果報文中包含Transfer-Encoding: chunked首部, 那麼Content-Length將被忽略.