計算機面試重難點之計算機網路

WINLSR發表於2021-08-03

TCP(傳輸層)

TCP報文段頭部

img

每個 TCP 段都包含源端和目的端的埠號,用於尋找傳送方和接收方應用程式。這兩個值加 上 IP 首部中的源端 IP 地址和目的端 IP 地址唯一確定一個 TCP 連線。

首部固定部分各欄位意義如下:

  • 源埠和目的埠:各佔 2 個位元組,分別寫入源埠和目的埠。IP 地址 + 埠號就可以確定一臺主機的一個程式地址

  • 序號/序列號(Sequense Number,SN):在一個 TCP 連線中傳送的位元組流中的每一個位元組都按順序編號。該欄位表示本報文段所傳送的資料的第一個位元組的序號。初始序號稱為 Init Sequense Number, ISN(專指TCP三次握手時前兩次握手的報文段中的序號)

    例如,一報文段的序號是 101,共有 100 位元組的資料。這就表明:本報文段的資料的第一個位元組的序號是 101,最後一個位元組的序號是 200。顯然,下一個報文段的資料序號應當從 201 開始,即下一個報文段的序號欄位值應為 201。

  • 確認號 ack:期望收到對方下一個報文段的第一個資料位元組的序號。若確認號為 N,則表明:到序號 N-1 為止的所有資料都已正確收到。

  • 資料偏移(首部長度):它指出 TCP 報文段的資料起始處距離 TCP 報文段的起始處有多遠。這個欄位實際上是指出TCP報文段的首部長度。

  • 保留:佔 6 位,應置為 0,保留為今後使用。

6 個控制位非常重要:

  • 緊急位 URG:當 URG = 1 時,表明此報文段中有緊急資料,是高優先順序的資料,應儘快傳送,不用在快取中排隊。該控制位需配合緊急指標使用。

    舉個例子:我們需要取消一個已經傳送了很長程式的執行,因此使用者從鍵盤發出中斷命令。如果不使用緊急資料,那麼這個指令將儲存在接收 TCP 的快取末尾,只有在所有的資料被處理完畢後這兩個字元才被交付接收方的應用程式,這樣做就無法實現立即中斷。

  • 確認 ACK:僅當 ACK = 1 時確認號欄位才有效,當 ACK = 0 時確認號無效。TCP 規定,在連線建立後所有傳送的報文段都必須把 ACK 置為 1

  • 推送 PSH:接收方收到PSH = 1 的報文段,就儘快地交付到上層應用程式。而不用等到整個快取都填滿了後再向上交付。當兩個應用程式進行互動式的通訊時,有時傳送方的應用程式希望在鍵入一個命令後立即就能收到對方的響應。在這種情況下,傳送方可以建立一個報文段並把 PSH 置為 1傳送出去。

  • 復位 RST:當 RST = 1 時,表明 TCP 連線中出現了嚴重錯誤(如由於主機崩潰或其他原因),必須釋放連線,然後再重新建立傳輸連線。

  • 同步 SYNSYN = 1 表示這是一個連線請求連線確認報文段。當 SYN = 1ACK = 0 時,表明這是一個連線請求報文段。對方若同意建立連線,則應在響應的連線確認報文段中使 SYN = 1ACK = 1

  • 終止 FIN:用來釋放一個連線。當 FIN = 1時,表明此報文段的傳送方資料已傳送完畢,並要求釋放TCP連線。

  • 視窗:用於流量控制,指明雙方的視窗大小。

  • 校驗和:傳送方初始校驗和欄位為0,對TCP 首部(包含12位元組的偽首部)和 TCP 資料每個 16 bit 進行二進位制反碼的求和,然後重新填入校驗和欄位。接收方收到資料後以同樣的方式計算校驗和,但接收方在計算過程中包含了傳送方存在首部中的檢驗和,因此,如果傳輸過程中沒有發生任何差錯, 那麼接收方計算的校驗和結果應該為全1。

    舉例:假設傳送方計算的校驗和為10101010。如果傳輸無誤,那麼接收方收到時,不包含校驗和欄位計算的反碼求和應該為10101010,再加上校驗和欄位的反碼(01010101)即為最終的校驗和:11111111

  • 緊急指標:當 URG = 1 時,該欄位才有效。關於緊急指標是指向緊急資料的最後一個位元組還是指向緊急資料最後一個位元組的下一個位元組的爭論。最初的TCP規範給出了兩種解釋,但Host Requirements RFC確定指向最後一個位元組是正確的。然而,問題在於大多數的實現(包括源自伯克利的實現)繼續使用錯誤的解釋。所有符合Host Requirements RFC的實現都是可相容的,但很有可能無法與其他大多數主機正確通訊。

三次握手過程

image-20210714210438779

三次握手(Three-way Handshake)指客戶端和伺服器建立一個TCP連線時,雙方總共需要傳送3個報文段。目的:確認雙方的接收能力和傳送能力是否正常同時指定雙方的初始化序列號(ISN)為後面的可靠性傳送做準備

剛開始服務端處於監聽狀態,進行三次握手由客戶端主動發起:

  1. 第一次握手:客戶端給服務端發一個 連線請求報文段,頭部指明SYN=1ACK=0以及初始化序列號 ISNseq=x)。此報文段不能攜帶資料,但要消耗掉一個序號。隨後客戶端進入 SYN_SENT (同步傳送)狀態。

  2. 第二次握手:服務端收到客戶端的 連線請求報文段之後,向客戶端傳送連線確認報文段,頭部指明SYN=1ACK=1,確認號(ack)為 x+1,並且也選擇一個初始化序列號y。隨後伺服器進入 SYN_RCVD (同步接收)的狀態。

  3. 第三次握手:客戶端收到服務端的 連線確認報文段之後,會向服務端回送一個確認報文段,頭部指明ACK=1,確認號ack=y+1,序號seq=x+1,該報文段可以攜帶資料,不攜帶資料則不消耗序號。隨後客戶端進入 ESTABLISHED (連線已建立)狀態。待伺服器收到客戶端傳送的 ACK 報文段也會進入 ESTABLISHED 狀態,完成三次握手。

三次握手為什麼不能是兩次?

  1. 首先需要明確:三次握手是為了讓客戶端和服務端確認對方的傳送能力以及接受能力都是正常的

    第一次握手:客戶端傳送報文段,服務端收到了。
    這樣服務端就能得出結論:客戶端的傳送能力、服務端的接收能力是正常的。

    第二次握手:服務端傳送報文段,客戶端收到了。
    這樣客戶端就能得出結論:服務端的接收、傳送能力,客戶端的接收、傳送能力是正常的。不過此時伺服器並不能確認客戶端的接收能力是否正常。

    第三次握手:客戶端傳送報文段,服務端收到了。
    這樣服務端就能得出結論:客戶端的接收、傳送能力正常,伺服器自己的傳送、接收能力也正常。

    因此,改成兩次握手,服務端不能確定傳送端的接收能力是否正常

  2. 且可能存在以下情況:客戶端向服務端傳送 連線請求報文段,但由於網路原因滯留在網路中。客戶端超時重傳了一個新的連線請求報文段,利用新的請求客戶端和服務端成功建立連線並通訊,通訊完後關閉釋放了連線。但此時舊的(失效的)連線請求報文段重新到達服務端,如果採用兩次握手建立連線那麼就會導致服務端建立錯誤的連線。

  3. 其次兩次握手,就建立連線,會放大 DDOS 攻擊

什麼是半連線佇列

伺服器第一次收到客戶端的連線請求報文段之後,就會處於SYN_RCVD(同步接收) 狀態,此時雙方還沒有完全建立其連線,伺服器會把此種狀態下請求連線放在一個佇列裡,我們把這種佇列稱之為半連線佇列

當然還有一個全連線佇列,就是已經完成三次握手,建立起連線的就會放在全連線佇列中。如果佇列滿了就有可能會出現丟包現象。

ISN(Initial Sequence Number)是固定的嗎?

TCP建立連線時會確定客戶端和服務端的ISN並交換,他們是後序所傳送位元組資料編號的原點。ISN是通過隨機生成演算法生成的,如果ISN是固定的,攻擊者很容易猜出後續的確認號,因此 ISN 是動態生成的。此外,如果相同客戶端和服務端的前後兩次連線的ISN的相同,第一次連線結束後,第二次連線資料傳輸過程中,屬於前一次連線但滯留在網路中的報文段突然又到達服務端,伺服器是沒法區分的

備註:RFC1948中提出了一個較好的初始化序列號ISN隨機生成演算法。ISN = M + F(localhost, localport, remotehost, remoteport)M是一個計時器,這個計時器每隔4毫秒加1。F是一個Hash演算法,根據源IP目的IP源埠目的埠生成一個隨機數值。要保證hash演算法不能被外部輕易推算得出,用MD5演算法是一個比較好的選擇。

三次握手過程中可以攜帶資料嗎?

第一次、第二次握手不可以攜帶資料,而第三次握手是可以攜帶資料的。

假如第一次握手可以攜帶資料的話,如果有人要惡意攻擊伺服器,那他每次都在第一次握手中的 連線請求報文段中放入大量的資料,並瘋狂重發。這會讓伺服器花費大量的記憶體空間來快取這些報文段,這樣伺服器就更容易被攻擊了。

對於第三次握手,此時客戶端已經處於連線狀態,他已經知道伺服器的接收、傳送能力是正常的了,所以可以攜帶資料是情理之中。

SYN攻擊是什麼?

SYN 攻擊是一種典型的 DoS/DDoS(Distributed Denial of Service) 攻擊,攻擊方利用伺服器端的資源是在二次握手時分配的這一特徵進行攻擊。SYN攻擊就是攻擊端在短時間內偽造大量不存在的IP地址,並向服務端不斷地傳送連線請求報文段,服務端則回覆連線確認報文段,並等待攻擊端的確認報文段,由於源地址是偽造的,因此服務端需要不斷重發直至超時,這些偽造的連線請求報文段導致大量的請求連線長時間佔用半連線佇列,導致正常的請求連線因為佇列滿而被丟棄,從而引起網路擁塞甚至系統癱瘓。

第三次握手失敗怎麼辦?

客戶端收到服務端的連線確認報文段後,其狀態變為ESTABLISHED,並會傳送確認報文段給服務端,準備傳送資料了。如果此時確認報文段在網路中丟失,並且超時,那麼服務端會重新傳送連線確認報文段。如果重傳指定次數之後仍然未收到客戶端的確認報文段,服務端將自動關閉這個連線。但是客戶端認為這個連線已經建立,如果客戶端向服務端發資料,服務端將以復位報文段響應,客戶端方能感知到服務端的錯誤。

四次揮手過程

image-20210715111433026

四次揮手(Four-way handshake)指主動方和和被動方斷開 TCP 連線需要傳送四個包,客戶端或服務端均可主動發起揮手動作。

揮手前,雙方都處於ESTABLISHED 狀態,假如是客戶端先發起關閉請求,對應過程如下:

  • 第一次揮手:客戶端向服務端傳送一個連線釋放報文段,頭部指明FIN=1,序號seq=u。並停止傳送資料,主動關閉TCP連線。隨後客戶端進入 FIN_WAIT1 (終止等待1)狀態,等待服務端的確認。
  • 第二次揮手:服務端收到客戶端發來的連線釋放報文段後,回送 確認報文段,頭部指明ACK=1,確認號ack=u+1,序號seq=v,隨後服務端進入 CLOSE_WAIT(關閉等待) 狀態。客戶端收到服務端的確認報文段後,進入FIN_WAIT2(終止等待2)狀態,等待服務端發出的連線釋放報文段
  • 第三次揮手:如果服務端也想斷開連線了,和客戶端的第一次揮手一樣,向客戶端傳送連線釋放報文段,頭部指明FIN=1ACK=1,序號seq=w,確認號ack=u+1,隨後服務端進入LAST_ACK(最後確認)狀態,等待客戶端的確認報文段
  • 第四次揮手:客戶端收到 連線釋放報文段之後,同樣向服務端發出確認報文段,頭部指明ACK=1seq=u+1ack=w+1,此時客戶端進入 TIME_WAIT 狀態。服務端收到客戶端的確認報文段之後,進入 CLOSED 狀態。客戶端必須經過 2*MSL 後才進入 CLOSED 狀態。此時TCP連線已經完全釋放。

建立連線只需要握手三次,關閉連線時需要揮手四次呢?

其實在 TCP 第二次握手的時候,服務端傳送的 連線確認報文段 將一個 ACK 和一個 SYN 合併到一起傳送給服務端,所以減少了一次包的傳送,三次便完成握手。對於四次揮手,因為 TCP 是全雙工通訊,在主動方傳送連線釋放報文段後,被動方可能還要傳送資料,不能立即關閉被動方到主動方的資料通道,所以被動方不能將確認報文段連線釋放報文段合併回送給主動方。只能先傳送將確認報文段回送給主動方,然後待被動方無需傳送資料時再回送 連線釋放報文段,所以四次揮手必須使用四次資料包互動。

四次揮手時,主動方等待2MSL的意義?

MSLMaximum Segment Lifetime的英文縮寫,指“報文段在網路中最大生存時間”,超過這個時間報文段將被丟棄。

  1. 保證主動方傳送的最後一個確認報文段能夠到達被動方

    這個確認報文段有可能丟失,使得處於LAST-ACK(最後確認)狀態的被動方收不到該報文段,被動方超時重傳連線釋放報文段,而主動方能在2MSL時間內收到這個重傳的連線釋放報文段,接著主動方重傳一次確認報文段,重啟2MSL計時器,最後雙方都進入到CLOSED狀態。若主動方發完確認報文段後立即釋放連線,被動方在超時未收到確認報文段的情況就不能正常處理,就導致被動方無法正常進入到CLOSED狀態。

  2. 防止“已失效的連線請求報文段”出現在本連線中

    主動方傳送完最後一個確認報文段,再經過2MSL,就可以使本連線持續的時間內所產生的所有報文段都從網路中消失,使下一個新的連線中不會出現這種舊的連線請求報文段。

其他

如果已經建立了連線,但是客戶端突然出現故障了怎麼辦?

TCP設有一個保活計時器,伺服器每收到一次客戶端的TCP報文段後都會重新復位這個計時器,時間通常是設定為2小時。客戶端如果出現故障若,導致服務端兩小時都沒有收到客戶端的任何資料,伺服器就會每隔75秒鐘傳送一個探測報文段,若一連傳送10個探測報文段仍然沒反應,伺服器就認為客戶端出了故障,接著就關閉連線。

TCP依靠哪些機制來保證可靠傳輸?

  1. 校驗和TCP通過校驗和檢測資料在傳輸過程中是否發生改變,如果收到的報文段的校驗和有差錯,報文段將被丟棄。

  2. 序列號確認應答TCP 給傳送的每一個報文段中都有序號欄位,每次接收方收到資料後,都會對傳輸方進行確認應答,即傳送確認報文段(ACK) ,其中的確認號告訴傳送方成功接收了哪些資料以及下一次的資料從哪裡開始發。除此之外,接收方可以根據序列號對資料包進行排序,把有序資料傳送給應用層,並丟棄重複的資料。

  3. 超時重傳:當 TCP 發出一個報文段後,它將啟動一個定時器,等待接收端發回的確認。如果超過定時器超時還沒有收到確認,傳送方將重發這個報文段。

  4. 約定最大報文段長度(MSS):在建立TCP連線的時候,雙方約定最大報文段長度作為傳送的單位,理想的情況下是該長度的資料剛好不被網路層分片。

  5. 流量控制TCP通過滑動視窗機制實現流量控制,視窗(緩衝區)的大小就是傳送方在無需等待確認報文段的情況下還能傳送的最大資料量。TCP通過視窗大小來協調端對端的傳送速度,確保接收端來得及接收,從而儘可能減少丟包。

  6. 擁塞控制:通過擁塞控制演算法(慢開始、擁塞避免、快重傳、快恢復),根據全域性網路的擁塞程度來調整擁塞視窗的大小,改善網路擁塞程度,從而儘可能減少丟包。

    備註:傳送視窗的大小等於Min(接收視窗, 擁塞視窗),因此是兩種流量控制擁塞控制的共同作用。

ARQ協議與滑動視窗機制的關係?

自動重傳請求 ( Automatic Repeat-reQuest , ARQ )是 OSI模型 中 資料鏈路層傳輸層 的錯誤糾正協議之一。其利用確認超時這兩個機制,可以在不可靠服務的基礎上實現可靠的資訊傳輸。ARQ協議分等停ARQ協議連續ARQ協議,連續ARQ協議採用了滑動視窗機制,後者又可分為後退N步協議選擇重傳協議

擁塞控制有哪些演算法?

擁塞控制演算法:慢開始、擁塞避免、快重傳、快恢復。這些演算法會根據網路不同的擁塞狀況來搭配使用。

慢開始演算法:在一開始不清楚網路擁塞程度時,避免一開始就向網路中注入大量資料,由小到大逐漸增大擁塞視窗數值。cwnd(擁塞視窗) 初始值設為為 1,每經過一個傳輸輪次transmission round),cwnd 加倍。(慢開始並不是指cwnd增長慢)。當擁塞視窗達到慢開始門限值 ssthresh,改用擁塞避免演算法。(當cwnd = ssthresh時,既可使用慢開始演算法,也可使用擁塞避免演算法)。

image-20210717061407522

擁塞避免演算法: 擁塞避免演算法的思路是讓 cwnd 緩慢地增大,即每經過一個往返時間 RTT 就把傳送方的擁塞視窗 cwnd 加1,而不是加倍。這樣,擁塞視窗 cwnd 按線性規律緩慢增長,比慢開始演算法的擁塞視窗增長速率緩慢得多。

無論在慢開始階段還是在擁塞避免階段,只要傳送方判斷網路出現擁塞(計時器超時,未收到確認),就要把慢開始門限 ssthresh 設定為出現擁塞時的傳送視窗值的一半(但不能小於2)。然後把擁塞視窗 cwnd 重新設定為 1,執行慢開始演算法

image-20210717064412551

快重傳演算法:快重傳演算法要求接收方在收到一個失序的報文段後就立即發出重複確認而不要等到自己傳送資料時捎帶確認。傳送方只要一連收到三個重複確認就應當立即重傳對方尚未收到的報文段,而不必繼續等待設定的重傳計時器時間到期。(以便傳送方及早知道丟失發生,及早進行重傳)。與快重傳配合使用的還有快恢復演算法。

image-20210717064453713

快恢復演算法:當傳送方連續收到三個重複確認時,把 ssthresh 門限減半。考慮到如果網路出現擁塞的話就不會收到好幾個重複的確認,所以傳送方認為現在網路可能沒有出現擁塞。所以此時不執行慢開始演算法,而是將cwnd設定為ssthresh的大小,然後執行擁塞避免演算法

image-20210717064707907

流量控制與擁塞控制有何不同?

流量控制:採用端對端的機制,接收端通過視窗欄位告知傳送端自己的接收能力,進而協調傳送端的傳送速度,避免接收端來不及接收而丟包。

擁塞控制:採用面向全域性的機制,根據網路的擁塞程度來改變擁塞視窗,進而協調主機向網路中注入資料的速度,改善網路擁塞程度,從而儘可能減少丟包。

TCP 和 UDP 的區別?

型別 傳輸可靠性 是否面向連線 是否支援多播,廣播 傳輸形式 資源佔用 首部長度(位元組) 應用場景
TCP 可靠 面向位元組流 20 - 60 檔案,郵件傳輸
UDP 不可靠 面向報文段 8 即時通訊,直播等

TCP 提供可靠服務,在傳送資料之前必須先建立連線,資料傳送結束後要釋放連線;UDP與之相反,只盡最大努力交付。

TCP不提供廣播或多播服務;UDP則提供。

TCP是面向位元組流的;而UDP是面向報文段的。

TCP 要提供可靠的服務,建立連線,釋放連線,加之確認、視窗、重傳、流量控制、擁塞控制、定時器等機制都會佔用更多的系統資源,同時導致協議頭部增大(20 - 60 位元組);UDP則佔用較少系統資源,協議頭部也更小(僅 8 位元組)。

TCP提供可靠服務,故使用在檔案傳輸、郵件傳輸等場景;雖然 UDP 不提供可靠交付,但在某些情況下 UDP 確是一種最有效的工作方式,如即時通訊,直播等場景。

什麼是 TCP 粘包問題?

TCP粘包就是指傳送方應用層交給TCP傳送的若干資料包經過TCP傳輸到達接收方時合併粘成了一個資料包,出現粘包的原因是多方面的,可能是來自傳送方,也可能是來自接收方。

造成TCP粘包的原因?

  1. 傳送方原因

    TCP 預設使用 Nagle 演算法,當應用層交付給TCP傳送的資料包過於小時,傳送方會收集了多個較小的資料包進行合併傳送,這將會發生粘包。

  2. 接收方原因

    TCP傳送方傳送資料很快,接收方TCP緩衝區收到大量資料,但應用層取出資料的速度又太慢,造成多個資料包被快取,應用層就有可能讀取到多個首尾相接粘到一起的資料包。

什麼時候需要處理粘包問題?

  1. 如果傳送方傳送的多個資料包本來就是同一塊資料的不同部分就不需要處理粘包現象。
  2. 如果多個資料包毫不相干,甚至是並列關係,那麼這個時候就一定要處理粘包現象了。

如何處理粘包問題?

在應用層進行處理。如:

  1. 在應用層交給TCP的每個資料包頭部都新增長度欄位,接收方應用層讀取資料時根據資料包頭部長度欄位迴圈讀取相應長度的內容;
  2. 將應用層交給TCP的每個資料包的首、尾分別新增開始符、結束符。

HTTP(應用層)

HTTP協議是Hyper Text Transfer Protocol(超文字傳輸協議)的縮寫,是用於從全球資訊網(WWW:World Wide Web )伺服器傳輸超文字本地瀏覽器的傳送協議。HTTP是一個基於TCP/IP通訊協議來傳遞資料(HTML,圖片等檔案,以及查詢結果等)。

主要特點如下:

  1. 簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯絡的型別不同。由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。

  2. 靈活HTTP允許傳輸任意型別的資料物件。正在傳輸的型別由Content-Type加以標記。

  3. 無連線:無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線。採用這種方式可以節省傳輸時間。

  4. 無狀態HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。

  5. 支援B/SC/S模式

HTTP 協議由哪幾部分組成?

  1. 請求協議資訊由 4 部分組成:請求行、請求頭、空行、請求體

  2. 響應協議資訊也由 4 部分組成:狀態行、響應頭、空行、響應體

    使用curl命令檢視協議詳情:

    Snipaste_2021-07-19_12-59-49

HTTP狀態碼?

HTTP 狀態碼由三個十進位制數字組成,第一個數字定義了狀態碼的型別。HTTP 狀態碼共有 5 種型別:1xx, 2xx, 3xx, 4xx, 5xx。型別解釋以及部分常見狀態碼如下:

  1. 1XX (Informational) : 接收的請求正在處理

    100 Continue :表明請求到目前為止都處理的很正常,客戶端可以繼續傳送請求或者忽略這個響應。

  2. 2XX (Success) : 請求正常處理完畢

    200 OK : 表示成功處理了請求。

  3. 3XX (Redirection) : 需要進行附加操作以完成請求

    301 Moved Permanently :永久性重定向。

    302 Found :臨時性重定向。

  4. 4XX (Client Error) : 伺服器無法處理請求

    403 Forbidden :請求被伺服器拒絕。

    404 Not Found : 伺服器找不到請求的網頁。

  5. 5XX (Server Error) : 伺服器處理請求出錯

    500 Internal Server Error :伺服器正在執行請求時發生錯誤。

更多:Http協議計算機網路 HTTP狀態碼和首部

狀態碼 301 和 302 的區別?

301302狀態碼都表示重定向,就是說瀏覽器在拿到伺服器返回的這個狀態碼後會自動跳轉到一個新的URL地址,這個地址可以從響應頭部欄位Location中獲取(使用者看到的效果就是他輸入的地址A瞬間變成了另一個地址B

301: 表示永久重定向。該狀態碼錶示請求的資源已被分配了新的 URI,以後應使用資源現在所指的 URI。也就是說,如果已經把資源對應的 URI儲存為書籤了,這時應該按 Location 欄位提示的 URI 重新儲存。

302: 表示臨時重定向。該狀態碼錶示請求的資源已被分配了新的 URI,希望使用者(本次)能使用新的 URI 訪問。和 301 狀態碼相似,但 302 狀態碼代表的資源不是被永久移動,只是臨時性質的。換句話說,已移動的資源對應的URI 將來還有可能發生改變。比如,使用者把 URI 儲存成書籤,但不會像 301 狀態碼出現時那樣去更新書籤,而是仍舊保留返回 302 狀態碼的頁面對應的 URI

Forward和Redirect的區別?

Forward:客戶端發出的請求被伺服器內部進行轉發,瀏覽器位址列依然是之前的URL。就如 SpringMVC 中,所有的請求都由 DispatcherServlet處理後再在伺服器內部進行派發。

Redirect:實際是兩次HTTP請求,伺服器端在響應第一次請求的時候,讓瀏覽器再向另外一個URL發出請求,從而達到轉發的目的。

HTTP 請求方法瞭解哪些?

HTTP/1.0 定義了三種請求方法:GET, POST HEAD 方法。

方法 描述
GET 最常用的方法之一,用於請求伺服器響應某個資源,不應當對系統資源進行改變。
POST 最常用的方法之一,用於將資料(表單等)提交至伺服器以建立新的資源。
HEAD HEAD 方法與 GET 方法的行為很類似,但伺服器在響應中只返回首部,這就允許客戶端在未獲取實際資源的情況下,根據首部資訊對資源進行檢查。

HTTP/1.1新增了:PUTPATCHDELETECONNECTOPTIONSTRACE 共5種HTTP請求方法。

方法 描述
PUT 用於將資料提交至伺服器以更新之前存在的資源。
PATCH 是對 PUT 方法的補充,用來對已知資源進行區域性更新;當資源不存在時,PATCH會建立一個新的資源。
DELETE 請求伺服器刪除指定的資源。
CONNECT HTTP/1.1 協議中預留給能夠將連線改為管道方式的代理伺服器。
OPTIONS 請求伺服器告知其支援的各種功能。
TRACE 請求伺服器回顯其收到的請求,主要用於測試或診斷。

備註HTTP規範定義了以上方法的行為,但實際開發中可以不遵守。例如:在GET請求對應的介面中去更新資源,將會給自己帶來麻煩。

HTTP冪等性瞭解嗎?

在程式設計領域,對於同一個系統,在同樣條件下,一次請求和重複多次請求對服端資源的影響是一致的,就稱該操作為冪等的

HTTP常見冪等方法:GETPUTDELETE

HTTP常見非冪等方法:POSTPATCH

解釋:

PUT第一次和第N次請求對服務端資源的影響是相同的,所以是冪等的。例如將id1234的賬戶金額改為1000,多次呼叫對系統資源產生的影響是一致的。

DELETE第一次和第N次請求對服務端資源的影響是相同的,所以是冪等的。假如存在一個刪除 id 1234 的賬戶的介面,第一次請求時會刪除,而後面所有請求的時候由於系統中已經沒有該資源了,所以第一次和後面的請求對服務端資源的影響( id 1234 的資源不再存在)是相同的。

PATCH: URI 對應的資源不存在時服務端可以建立一個新資源,因此兩次請求對服務端資源的影響可能會不同。並且服務端可以根據請求引數,動態的計算出某個值,例如每次請求後資源的某個引數減1,所以多次呼叫,資源會有不同的變化。綜上,PATCH方法是非冪等的。

更多:聊聊開發中冪等性問題

瞭解REST風格嗎?

REST是一種架構風格,即Representational State Transfer的縮寫,譯為"表現層狀態轉化"。REST的原則不僅僅適用於HTTP協議,但由於REST的應用場景絕大部分是WEB應用,故以下討論都基於HTTP

資源是網路上的一個實體,或者說是網路上的一個具體資訊,一個資源可以被URI唯一標識。因此,表現層可以理解為資源的一種具體表現,如:文字檔案、html檔案等等。狀態轉化指客戶端和服務端的互動過程中通過HTTP協議提供的4個動作(GET用來獲取資源,POST用來新建資源,PUT用來更新資源,DELETE用來刪除資源。)對伺服器資源進行操作,從而實現"表現層狀態轉化"。

備註:而RESTful API就是符合REST風格的API

更多:理解RESTful架構詳解REST架構風格

GET 和 POST 的區別?

  1. 從功能上講,GET 一般用來從伺服器上獲取資源,POST 一般用來在伺服器上新增資源;
  2. REST 服務角度上說,GET 是冪等的,而 POST 不是冪等的;
  3. 從請求引數形式上看,GET 請求的資料會附在 URL 之後,POST 請求會把提交的資料放置在是 HTTP 請求報文的請求體中;
  4. 就安全性而言,POST 的安全性要比 GET 的安全性高,因為 GET 請求提交的資料將明文出現在 URL 上,而且 POST 請求引數則被包裝到請求體中,相對更安全;
  5. 從請求的大小看,GET 請求的長度受限於瀏覽器或伺服器對 URL 長度的限制,允許傳送的資料量比較小,而 POST 請求理論上是沒有大小限制。

怎麼知道 HTTP 的報文長度?

當傳輸的是靜態檔案時,服務端能夠很清楚的知道將要響應內容的大小,可以通過響應頭中的Content-Length 域來告訴客戶端報文的長度。如果服務端預先不知道將要響應內容的大小(動態生成的頁面)就需要在響應頭中指明 Transfer-Encoding: chunked 。表示響應體是使用chunked分塊方式拼接成的,不需要Content-Length指明長度。每一個分塊包含十六進位制的長度值資料,最後一個分塊長度值為0,表示實體結束,客戶端可以以此為標誌確認資料已經接收完畢。(這些是HTTP1.1的內容,Content-Length欄位不是必需的,因為瀏覽器發現伺服器關閉了TCP連線,就表明收到的資料包已經全了)。

Keep-Alive(長連線) 和 非 Keep-Alive 區別?

可以通過請求頭或響應頭中的Connection域檢視是否是Keep-Alive

短連線:在HTTP/1.0中預設使用短連線(也支援長連線,得手動設定Connection: keep-alive)。客戶端每個HTTP請求和響應都會開啟和關閉一個單獨的TCP連線。

長連線: 而從HTTP/1.1起,預設使用長連線。同一個客戶端和服務端之間的連續的多個HTTP請求和響應可以通過一個TCP連線來完成。但是一個長連線也不是一直保持,客戶端在最後一個請求時,傳送Connection: close,明確要求伺服器關閉TCP連線,也可以通過 keep-alive timeout 引數來設定。

HTTP1.0、HTTP1.1、HTTP2的主要變化?

HTTP1.1變化:

長連線HTTP1.0 預設是短連線,HTTP1.1 預設支援長連線,且引入了流水線技術(pipelining)。不僅多個請求可以複用同一個TCP連線,並且同一個TCP連線裡面,客戶端可以同時傳送多個請求。這樣就進一步改進了HTTP協議的效率。(流水線方式會存在"隊頭阻塞":如果第一個請求被阻塞,即使後到的請求已經處理完畢,響應時依然要按請求的順序依次響應)。

寬頻和網路連線優化HTTP1.0 會存在一些效能浪費,每次請求都返回整個物件,即使只需要物件的一部分。HTTP1.1則可以通過設定range頭域,僅請求返回資源的某一部分,也就是返回碼為206(Partial Content)的時候,這對於效能優化很有必要。

引入Host頭域HTTP1.1 新增了Host頭域,請求頭如果沒指定Host,則返回404。在HTTP1.0 中認為每個IP地址都只屬於一臺伺服器,因此,請求訊息中的URL並沒有傳遞主機名。但隨著虛擬主機技術的發展,在一臺物理主機上可以存在多個虛擬主機,並且它們共享一個IP地址,僅靠IP地址無法區分請求的是哪個虛擬主機,故HTTP1.1加上了Host頭域來區分。

更多:HTTP中的Host欄位

HTTP2 的變化:

二進位制HTTP1.X (頭資訊肯定是文字(ASCII編碼),資料體可以是文字,也可以是二進位制)的協議解析是基於文字格式,而HTTP2(頭資訊和資料體都是二進位制,並且統稱為"幀"(frame):頭資訊幀和資料幀)的協議解析是二進位制格式,解析更加高效。

多路複用(Mutiplexing) : 可以複用TCP連線,在一個連線裡,客戶端和瀏覽器都可以同時傳送多個請求或回應,而且不用按照順序一一對應,這樣就避免了"隊頭堵塞"

header壓縮: HTTP1.X 協議不帶有狀態,每次請求都必須附上所有資訊。所以,請求的很多欄位都是重複的,比如CookieUser Agent,一模一樣的內容,每次請求都必須附帶,這會浪費很多頻寬,也影響速度。HTTP2對這一點做了優化,引入了頭資訊壓縮機制(header compression)。一方面,頭資訊使用gzipcompress壓縮後再傳送;另一方面,客戶端和伺服器同時維護一張“首部表”來跟蹤和儲存之前傳送的頭域(鍵-值對),對於不變的域,不再通過每次請求和響應傳送;通訊期間幾乎不會改變的通用域鍵(User Agent、Accept等等) 只需傳送一次。

服務端推送(server push): 允許伺服器未經請求,主動向客戶端傳送資源,這叫做伺服器推送。常見場景是客戶端請求一個網頁,這個網頁裡面包含很多靜態資源。正常情況下,客戶端必須收到網頁後,解析HTML原始碼,發現有靜態資源,再發出靜態資源請求。其實,伺服器可以預期到客戶端請求網頁後,很可能會再請求靜態資源,所以就主動把這些靜態資源隨著網頁一起發給客戶端了。

更多:一篇文章讀懂 HTTP1.0 HTTP1.1 HTTP2.0 HTTPS

HTTP 和 HTTPS 的主要區別?

埠:HTTP協議埠為80,HTTPS協議埠為443;

安全性:HTTP資訊是明文傳輸;而HTTPS協議的資訊是經過SSL/TLS協議加密後傳輸的。( TLS (Transport Layer Security,傳輸層安全協議) 是 SSL (Secure Socket Layer,安全套接字層)的升級版)。

數字證書:HTTPS協議需要到 CA (Certificate Authority)機構申請數字證書,絕大多數需要花錢申請。

響應速度和資源消耗:HTTPS 相比 HTTP TCP 之上多了 SSL/TLS 協議,因此響應速度會更慢,資源消耗會更多。

HTTPS 的工作過程?

前置:SSL/TLS中使用了非對稱加密,對稱加密以及HASH演算法。

對稱加密:加解密祕鑰一樣,優點是加解密速度快,適合對大量資料加密;缺點是使用前需要傳輸給另一個使用方,容易洩露。

非對稱加密:分為私鑰和公鑰,私鑰自己儲存無需傳送,公鑰則是公開的,公鑰加密的資訊只有私鑰能解密(反之亦然)。非對稱加密加解密速度慢,只適合少量資料加密。

完整性校驗演算法(hash演算法):同一資料計算結果相同,一旦資料被修改結果就會改變。通常用來檢查資料是否被篡改。

HTTPS請求實際上包含了兩次HTTP傳輸,可以細分為 4 步:

  1. 客戶端向伺服器發起HTTPS請求,連線到伺服器的443埠。
  2. 伺服器將自己向 CA 申請的數字證書傳送給客戶端。數字證書包含了公鑰、簽名等資訊。
  3. 客戶端解析證書並對其進行驗證。如果證書不是可信機構頒佈,或者證書中的域名與實際域名不一 致,或者證書已經過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通訊。 如果證書沒有問題,客戶端就會從伺服器證書中取出伺服器的公鑰。然後客戶端還會生成一個隨機碼 KEY,並使用公鑰將其加密。隨後客戶端把加密後的隨機碼 KEY 傳送給伺服器,作為後面對稱加密的金鑰。
  4. 伺服器在收到訊息後使用私鑰解密得到隨機碼 KEY,到此客戶端和伺服器就已經成功建立了安全連線。接下來就可以用對稱加密進行通訊了。

Cookie是什麼?

HTTP Cookie(也叫 Web Cookie瀏覽器 Cookie)是伺服器傳送到使用者瀏覽器並儲存在本地的一小塊資料,它會在瀏覽器下次向同一伺服器再發起請求時被攜帶併傳送到伺服器上。通常可以用於個性化設定,瀏覽器行為跟蹤。

Session是什麼?

由於HTTP協議是無狀態的協議,所以伺服器需要記錄使用者狀態時就需要藉助Session機制。目前Session常見實現要藉助Cookie,即伺服器端建立一個Session物件,同時會建立一個特殊的Cookie物件(name為"JSESSIONID",valueSession物件的ID),然後將該Cookie物件傳送至瀏覽器。當瀏覽器端傳送第N(N>1)次請求到同一伺服器時就會攜帶該nameJSESSIONIDCookie物件。伺服器根據nameJSESSIONIDCookievalue(sessionId)去查詢對應Session物件,從而區分不同使用者。(Session物件預設存活30分鐘)

Cookie和Session的區別?

  1. 作用範圍不同,Cookie 儲存在客戶端(瀏覽器),Session 儲存在伺服器端。
  2. 存取方式的不同,Cookie 只能儲存 ASCII編碼的字元,Session 可以存任意資料型別,一般情況下我們可以在 Session 中保持一些常用變數資訊,比如說 商品ID商品數量(購物車場景)等。
  3. 有效期不同,Cookie 可設定為長時間保持,比如我們經常使用的預設登入功能,Session 一般失效時間較短,客戶端關閉或者 Session 超時都會失效(Session物件預設存活30分鐘)。
  4. 隱私策略不同,Cookie 儲存在客戶端,比較容易遭到不法獲取,早期有人將使用者的登入名和密碼 儲存在 Cookie 中導致資訊被竊取;Session 儲存在服務端,安全性相對 Cookie 要好一些。
  5. 儲存大小不同, 單個 Cookie 儲存的資料量 <= 4KB;對於Session來說並沒有上限,但出於對伺服器端的效能考慮,Session內不要存放過多的東西,並且應設定Session刪除機制。

在瀏覽器中輸入 URL 地址到顯示主頁的過程?

  1. 首先根據URL進行域名解析,得到對應IP地址。解析時,首先檢視瀏覽器DNS快取是否命中,沒有的話再檢視作業系統DNS快取hosts檔案)是否命中,如果再沒有命中就會藉助域名伺服器進行解析。
  2. 位於應用層瀏覽器的封裝好HTTP請求報文後交給應用層的TCP協議。
  3. TCP協議根據IP地址向伺服器的80埠發起三次握手以建立TCP連線,隨後將HTTP報文作為自己的資料部分封裝到TCP報文段中傳送出去。
  4. 伺服器上的TCP協議收到TCP報文段後進行拆包得到HTTP請求報文,HTTP請求報文隨後被應用層的伺服器程式讀取、解析和處理後,按照之前類似步驟響應資料給瀏覽器。
  5. 瀏覽器得到HTTP響應報文後進行解析,渲染並顯示給使用者。

計算機分層模型

  1. OSI 七層模型:大而全,但是比較複雜、而且是先有了理論模型,沒有實際應用。
  2. TCP/IP 四層模型:是由實際應用發展總結出來的,從實質上講,TCP/IP只有最上面三層,最下面一 層沒有什麼具體內容,TCP/IP參考模型沒有真正描述這一層的實現。
  3. 五層模型:五層模型只出現在計算機網路教學過程中,這是對七層模型和四層模型的一個折中,既 簡潔又能將概念闡述清楚。

三種模型以及對應層次關係如下:

image-20210720224206721

OSI七層網路體系結構各層的主要功能:

  1. 應用層:為應用程式提供互動服務。在網際網路中的應用層協議很多,如域名系統DNS,支援全球資訊網 應用的HTTP協議,支援電子郵件的SMTP協議等。

  2. 表示層:主要負責資料格式的轉換,如加密解密、轉換翻譯、壓縮解壓縮等。

  3. 會話層:負責在網路中的兩節點之間建立、維持和終止通訊,如伺服器驗證使用者登入便是由會話層 完成的。

  4. 運輸層:有時也譯為傳輸層,向主機程式提供通用的資料傳輸服務。該層主要有以下兩種協議:

    • TCP:提供面向連線的、可靠的資料傳輸服務;

    • UDP:提供無連線的、盡最大努力的資料傳輸服務,但不保證資料傳輸的可靠性。

  5. 網路層:選擇合適的路由和交換結點,確保資料及時傳送。主要包括IP協議。

  6. 資料鏈路層:資料鏈路層通常簡稱為鏈路層。將網路層傳下來的IP資料包組裝成幀,並再相鄰節點 的鏈路上傳送幀。

  7. 物理層 :實現相鄰節點間位元流的透明傳輸,儘可能遮蔽傳輸介質和通訊手段的差異。

相關文章