天天看點

知識梳理系列之四——網絡協定(TCP/IP、Http/Https)網絡分層模型若幹問題

知識梳理系列之四——網絡協定TCP/IP、Http/Https

  • 網絡分層模型若幹問題
    • OSI七層模型和TCP/IP四層模型
    • TCP/IP的握手與揮手
      • 三次握手:
      • 為什麼要三次握手?
      • 四次揮手
      • 為什麼要四次揮手?
    • HTTP協定與HTTPS協定
    • HTTP的Cache、Cookies、Session、Token等機制
      • Cache
      • Cookies、Session、Token

網絡分層模型若幹問題

本文是對基本知識的個人總結,旨在面試遇到時,能邏輯條理清晰。不是全面知識學習文本。

OSI七層模型和TCP/IP四層模型

  1. OSI七層網絡模型和TCP/IP四層模型圖示
    知識梳理系列之四——網絡協定(TCP/IP、Http/Https)網絡分層模型若幹問題

    TCP/IP是一組協定族,包含很多協定,常見的比如UDP、HTTP、S-HTTP(HTTPS)、SSL/TLS、FTP、SMTP、POP3、DHCP、SOCKS等等,其中HTTP/FTP/SMTP/POP3/SOCKS等屬于應用層協定。TCP/UDP協定是網絡層協定、IP協定是傳輸層協定。

    Socket網絡套接字是一個使用TCP/IP的接口,友善通路和使用這些協定,本身不是協定。

  2. 其中HTTPS協定就是HTTP + SSL/TLS

    SSL是Secure Sockets Layer的縮寫,由Netscap釋出,經IEEE标準化為TLS,目前主流的是TLS 1.1、TLS 1.2版本。

  3. TCP與UDP的差別:

    a. TCP保證資料在網絡中的正确性、順序性,而UDP不保證;

    b. UDP由于不保證上述性質,省去了校驗正确和順序收發,在傳輸上更快速。

TCP/IP的握手與揮手

三次握手:

如下圖所示:

知識梳理系列之四——網絡協定(TCP/IP、Http/Https)網絡分層模型若幹問題

說明:三次握手步驟:

  • 用戶端服務端分别打開傳輸控制塊TCB,服務端進入LISTEN狀态,客服端發起請求,并帶資料SYN=1,seq=x(seq是一個序列數,序列數一般是發送資料的長度,握手時序列數都是+1不帶其他資料),發送後用戶端進入SYN_SEND狀态;
  • 服務端收到請求,并向用戶端回複資料:ACK=1,SYN=1,ack=x+1,seq=y(表示收到了用戶端的SYN=1,回複确認ACK=1,并且用戶端的序列數+1,自己的資料序列數y),服務端進入SYN_RCVD狀态;
  • 用戶端收到服務端的确認,并發送建立連接配接确認資料:ACK=1,ack=y+1,seq=x+1(表示用戶端收到了服務端的确認,并回複伺服器建立連接配接),用戶端進入ESTABLISH,服務端收到用戶端的确認資料後也進入ESTABLISH狀态,此時連接配接建立。

為什麼要三次握手?

可以看到完成第二次握手時,相當于服務端收到了用戶端的請求,并且用戶端也知曉的狀态,為什麼還需要進行第三次握手呢?

答案:主要是為了避免失效請求重複連接配接

一種常見場景:

一次用戶端請求發出後,網絡環境不暢,請求停留在網絡中,用戶端在長時間沒有收到回複,嘗試重新請求,此時網絡暢通,并成功建立連接配接,完成資料交換并關閉連接配接,此時停留在網絡中的上次請求又到達了伺服器。

此時,如果隻有兩次握手将再次建立連接配接,這是不符合預期的!并且造成資源浪費。

那麼是三次握手時,服務端收到失效的請求後,向用戶端發送确認資料,但是用戶端發現自己并沒有請求,于是不做回複,此時,避免了失效請求導緻重複連接配接!!

四次揮手

知識梳理系列之四——網絡協定(TCP/IP、Http/Https)網絡分層模型若幹問題

說明:四次揮手步驟:

  • 用戶端發起斷開連接配接請求,FIN=1,seq=u,用戶端進入FIN-WAIT-1狀态;
  • 服務端收到此請求後,回複用戶端:ACK=1,ack=u+1,seq=v(此時沒有回複FIN=1,因為服務端有可能有資料還沒有發送完,隻告知用戶端我收到了你的FIN請求,我還有資料沒發完),此時服務端進入CLOSE_WAIT狀态,用戶端進入FIN-WAIT-2狀态;
  • 直到服務端把最後的資料全部發送完成,服務端會再次向用戶端發送:FIN=1,ACK=1,ack=u+1,seq=w(表示我最後的資料已經發完了),服務端進入LAST_ACK狀态,等待用戶端收到确認;
  • 用戶端收到後,發送ACK=1,ack=w+1,seq=u+1(告知服務端我收到了),并進入TIME_WAIT狀态,服務端收到後就CLOSE了,用戶端在TIME_WAIT逾時後進入CLOSE。

為什麼要四次揮手?

分解成兩個問題:

  1. 為什麼服務端回複用戶端的FIN請求,有兩次一次ACK,一次FIN/ACK?

    因為服務端收到請求後,有可能還有用戶端請求的資料沒有發送完成,是以第一次ACK是告知用戶端我收到你的FIN請求了,第二次FIN/ACK是告知用戶端你要的資料我都發出去了。服務端等用戶端确認知曉其已經發送完了資料,如果期間逾時沒有收到确認,服務端還會重發。

  2. 為什麼用戶端CLOSE之前有TIME_WAIT?

    因為用戶端在收到FIN/ACK後需要給服務端ACK,告知我收到了,如果用戶端發完ACK,立即CLOSE,有可能服務端未收到ACK而關閉不了,TIME_WAIT保持用戶端未關閉,是的服務端沒有收到用戶端的ACK時還可以再重發FIN/ACK;

    另外一個作用是清除網絡中的無效封包。

HTTP協定與HTTPS協定

HTTP是一種超文本傳輸協定,通常使用統一資源定位符URL來擷取網絡資源。

  1. 請求封包格式

    請求頭: 請求方法(如GET/POST)     資源路徑或參數     HTTP協定版本

    請求行: 就是Request對象裡的一系列配置

          比如:Host、User-Agent、Content-Type、Content-Length、Content-Encoding、

          Content-Language、Accept-Type、Accept-Language、Connection(Keep-Alive)等等;

    空行

    請求體:(POST有/GET無)

  2. 響應封包格式

    狀态行: 協定版本     狀态碼     狀态短語

    響應頭: Date 時間日期

          charset 、Content-Type

          Content-Length等等

    空行

    響應正文:比如 json 字元串等

    狀态碼:

    狀态碼 含義
    1xx 繼續執行
    2xx 成功
    3xx 重定向
    4xx 用戶端錯誤
    5xx 服務端問題
  3. 與Https的差別

    差別在于在表示層使用了SSL/TLS,來進行身份校驗(伺服器CA憑證),并使用密文傳輸請求資料。

    http使用的是明文傳輸。

    https會犧牲一部分速度,但總體影響不大;

    常用的加密方式非對稱加密、對稱加密;

  4. 附:有趣的加密原理(Diffie-Hellman算法)

    非對稱加密的離散對數方案:

    已知公鑰: 質 數 p 、 α 質數p、\alpha 質數p、α

    ALICE要和BOB加密通信,不希望被EVE竊密;

    希望有一種加密方式,用已知的加密算法,ALICE用私鑰a加密資料Data發送給BOB,BOB接收到密文用自己的私鑰b就能解密;

    EVE隻能從網絡中拿到兩者加密後的資料,在一定時間内無法窮舉出密碼。

    ALICE: 将計算: y = α a   ( m o d p ) y = \alpha^a \ (mod \quad p) y=αa (modp) 将計算結果發送到網絡中;BOB和EVE都可以收到

    BOB:将計算: z = α b   ( m o d p ) z = \alpha^b \ (mod \quad p) z=αb (modp) 将計算結果發送到網絡中;ALICE和EVE都可以收到

    ALICE:将收到的z 進行計算: p r e M a s t e r K e y = z a   ( m o d p ) preMasterKey = z^a\ (mod \quad p) preMasterKey=za (modp)

    BOB:将收到的y 進行計算: p r e M a s t e r K e y = y b   ( m o d p ) preMasterKey = y^b\ (mod \quad p) preMasterKey=yb (modp)

    此時發現ALICE和BOB算出了一緻的結果preMasterKey ,這樣就完成了加密通信的建立,確定兩個身份合法的人連接配接到了一起,而EVE由于算不出一緻的結果而無法竊密。

其中mod就是取餘計算。

HTTP的Cache、Cookies、Session、Token等機制

  • 由于HTTP是無狀态協定,是以每次建立連接配接之間沒有聯系,如果遇到上一次的資料對下一個請求行為的結果有影響的情況,HTTP協定在協定層面是不好解決的,也不希望破壞無狀态的特性。

    于是就出現了Cookies、Session、Token等機制。

  • 而Cache機制主要是為了降低伺服器的負載,在一些場景下直接使用緩存而不是直接請求的方式節約資源、提高響應速度。

Cache

  1. 在響應封包的響應頭中有一個參數:Cache-control: 字段。

    這個字段就是設定緩存政策的。

    常見的緩存政策有:

緩存政策名 含義或用途
no-store 不儲存任何緩存,每次都重新請求伺服器擷取資料,相當于沒有緩存。
no-cache

儲存緩存,但是每次都先請求伺服器确認資料是否發生了變化。

1. 若資料未變化,伺服器傳回304,使用緩存資料;

2. 若資料變化,伺服器傳回新的資料供用戶端使用,用戶端更新緩存。

max-age 将設定一個最大新鮮時間。若未逾時,直接使用緩存;若逾時,向伺服器請求資料。
private 預設的配置,隻允許單個用戶端緩存
public 允許網絡代理和用戶端緩存
s-maxage 表示public的緩存的最大新鮮時間
max-stale 表示緩存過期後仍然可用的最大時間
min-fresh 表示響應擷取到後,緩存的最少新鮮時間,min-fresh不能大于max-age,否則失效導緻min-fresh=max-age
must-revalidate 在使用緩存之前必須驗證資源是否新鮮

一般,public和s-maxage組合使用;

no-cache的優先級更高,no-cache相當于max-age=0 + must-revalidate;

must-revalidate的優先級比max-age更高;

如果沒有no-cache或must-revalidate才執行下面的步驟:

a. 緩存目前的時間age+min-fresh <= max-age 時,認為緩存新鮮可用;

b. age+min-fresh > max-age && age+min-fresh <= max-age + max-stale時,表示雖然緩存已經過期了,但是仍然可用,響應頭會挂110 警告代碼;

c. age+min-fresh > max-age + max-stale時,表示緩存過期不可用,必須重新請求拉取資料。

  1. 對比緩存相關屬性

    響應頭除了會傳回Cache-control字段還會有其他的,主要是:ETag、If-Modified、If-Modified-Since、If-None-Match;

緩存字段名 含義或用途
ETag 是伺服器對某個請求的響應,目前的資源的一個特定辨別
If-None-Match 是客服端再次請求伺服器時,請求的這個資源的辨別

這兩個是一對,都是資源辨別,一個是第一次請求,服務端傳給用戶端的資源的代号;

一個是下次用戶端再請求時,回傳給服務端,要擷取的資源的代号。

緩存字段名 含義或用途
If-Modified 是伺服器響應的資源的時間辨別,是截止到響應為止,資源最新被修改的時間
If-Modified-Since

是用戶端再次請求資源時,回傳給伺服器的用戶端目前的資源時間辨別。

1. 若伺服器對應資源(相同ETag)的最新被修改時間變化了(If-Modified > If-Modified-Since),服務端将重新下發新的資源;

2. 若伺服器對應資源最新被修改時間未變,說明資源未變,傳回304直接用cache

這兩個也是一對,是一對各自持有的時間辨別。用來判斷資源是否修改。

總結:Cache-control 字段規定了是否緩存、緩存在哪、緩存逾時多久(過期時間);ETag/If-Modified系列确定了資源有沒有變化。

Cookies、Session、Token

Cookies、Session、Token都是為解決無狀态問題出現的,各有差别。

Cookies在服務端的響應頭中設定Set-cookies配置

Cookies是将狀态資料儲存在用戶端,在每次請求都自動帶上(對範圍有要求,隻能帶上>=的),這種的缺點是每次通路相同的伺服器頁面就會帶上,缺乏對使用者身份的驗證。

Session是服務端給用戶端配一個唯一的session id來标記用戶端,隻有session id由用戶端儲存,其餘資料都儲存在服務端。服務端每次根據用戶端請求時送出的session id在自己的散清單中查詢,來确定用戶端身份和資料。

session id的儲存形式可以是用戶端cookies儲存或者請求時作為參數的形式(不完全依靠cookies);

這種方式當遇到分布式服務,需要給各個主機拷貝session散清單,或者提供一台專門建立、儲存、查詢、删除session id的伺服器管理。

缺點就是:拷貝過程繁瑣,或者一旦專門服務挂了,整個系統就當機了。

Token就是專門針對Session的缺點提供的一種方案,由服務端密鑰和加密算法生成字元串并簽名後,授權給用戶端,用戶端隻需要儲存這個字元串,每次請求時上傳,由服務端解密、校驗簽名即可獲得使用者身份和狀态。

繼續閱讀