TCP(傳輸層)
TCP報文段頭部

每個 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連接中出現了嚴重錯誤(如由于主機崩潰或其他原因),必須釋放連接,然后再重新建立傳輸連接, -
同步 SYN:
SYN = 1表示這是一個連接請求或連接確認報文段,當SYN = 1而ACK = 0時,表明這是一個連接請求報文段,對方若同意建立連接,則應在回應的連接確認報文段中使SYN = 1且ACK = 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的實作都是可兼容的,但很有可能無法與其他大多數主機正確通信,
三次握手程序

三次握手(Three-way Handshake)指客戶端和服務器建立一個TCP連接時,雙方總共需要發送3個報文段,目的:確認雙方的接收能力和發送能力是否正常;同時指定雙方的初始化序列號(ISN)為后面的可靠性傳送做準備,
剛開始服務端處于監聽狀態,進行三次握手由客戶端主動發起:
-
第一次握手:客戶端給服務端發一個
連接請求報文段,頭部指明SYN=1,ACK=0以及初始化序列號ISN(seq=x),此報文段不能攜帶資料,但要消耗掉一個序號,隨后客戶端進入SYN_SENT(同步發送)狀態, -
第二次握手:服務端收到客戶端的
連接請求報文段之后,向客戶端發送連接確認報文段,頭部指明SYN=1,ACK=1,確認號(ack)為x+1,并且也選擇一個初始化序列號y,隨后服務器進入SYN_RCVD(同步接收)的狀態, -
第三次握手:客戶端收到服務端的
連接確認報文段之后,會向服務端回送一個確認報文段,頭部指明ACK=1,確認號ack=y+1,序號seq=x+1,該報文段可以攜帶資料,不攜帶資料則不消耗序號,隨后客戶端進入ESTABLISHED(連接已建立)狀態,待服務器收到客戶端發送的ACK報文段也會進入ESTABLISHED狀態,完成三次握手,
三次握手為什么不能是兩次?
-
首先需要明確:三次握手是為了讓客戶端和服務端確認對方的發送能力以及接受能力都是正常的,
第一次握手:客戶端發送報文段,服務端收到了,
這樣服務端就能得出結論:客戶端的發送能力、服務端的接收能力是正常的,第二次握手:服務端發送報文段,客戶端收到了,
這樣客戶端就能得出結論:服務端的接收、發送能力,客戶端的接收、發送能力是正常的,不過此時服務器并不能確認客戶端的接收能力是否正常,第三次握手:客戶端發送報文段,服務端收到了,
這樣服務端就能得出結論:客戶端的接收、發送能力正常,服務器自己的發送、接收能力也正常,因此,改成兩次握手,服務端不能確定發送端的接收能力是否正常,
-
且可能存在以下情況:客戶端向服務端發送
連接請求報文段,但由于網路原因滯留在網路中,客戶端超時重傳了一個新的連接請求報文段,利用新的請求客戶端和服務端成功建立連接并通信,通信完后關閉釋放了連接,但此時舊的(失效的)連接請求報文段重新到達服務端,如果采用兩次握手建立連接那么就會導致服務端建立錯誤的連接, -
其次兩次握手,就建立連接,會放大
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,并會發送確認報文段給服務端,準備發送資料了,如果此時確認報文段在網路中丟失,并且超時,那么服務端會重新發送連接確認報文段,如果重傳指定次數之后仍然未收到客戶端的確認報文段,服務端將自動關閉這個連接,但是客戶端認為這個連接已經建立,如果客戶端向服務端發資料,服務端將以復位報文段回應,客戶端方能感知到服務端的錯誤,
四次揮手程序

四次揮手(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=1,ACK=1,序號seq=w,確認號ack=u+1,隨后服務端進入LAST_ACK(最后確認)狀態,等待客戶端的確認報文段, - 第四次揮手:客戶端收到
連接釋放報文段之后,同樣向服務端發出確認報文段,頭部指明ACK=1,seq=u+1,ack=w+1,此時客戶端進入TIME_WAIT狀態,服務端收到客戶端的確認報文段之后,進入CLOSED狀態,客戶端必須經過2*MSL后才進入CLOSED狀態,此時TCP連接已經完全釋放,
建立連接只需要握手三次,關閉連接時需要揮手四次呢?
其實在 TCP第二次握手的時候,服務端發送的 連接確認報文段 將一個 ACK 和一個 SYN 合并到一起發送給服務端,所以減少了一次包的發送,三次便完成握手,對于四次揮手,因為 TCP是全雙工通信,在主動方發送連接釋放報文段后,被動方可能還要發送資料,不能立即關閉被動方到主動方的資料通道,所以被動方不能將確認報文段 與 連接釋放報文段合并回送給主動方,只能先發送將確認報文段回送給主動方,然后待被動方無需發送資料時再回送 連接釋放報文段,所以四次揮手必須使用四次資料包互動,
四次揮手時,主動方等待2MSL的意義?
MSL是
Maximum Segment Lifetime的英文縮寫,指“報文段在網路中最大生存時間”,超過這個時間報文段將被丟棄,
-
保證主動方發送的最后一個
確認報文段能夠到達被動方,這個
確認報文段有可能丟失,使得處于LAST-ACK(最后確認)狀態的被動方收不到該報文段,被動方超時重傳連接釋放報文段,而主動方能在2MSL時間內收到這個重傳的連接釋放報文段,接著主動方重傳一次確認報文段,重啟2MSL計時器,最后雙方都進入到CLOSED狀態,若主動方發完確認報文段后立即釋放連接,被動方在超時未收到確認報文段的情況就不能正常處理,就導致被動方無法正常進入到CLOSED狀態, -
防止“已失效的連接請求報文段”出現在本連接中,
主動方發送完最后一個
確認報文段,再經過2MSL,就可以使本連接持續的時間內所產生的所有報文段都從網路中消失,使下一個新的連接中不會出現這種舊的連接請求報文段,
其他
如果已經建立了連接,但是客戶端突然出現故障了怎么辦?
TCP設有一個保活計時器,服務器每收到一次客戶端的TCP報文段后都會重新復位這個計時器,時間通常是設定為2小時,客戶端如果出現故障若,導致服務端兩小時都沒有收到客戶端的任何資料,服務器就會每隔75秒鐘發送一個探測報文段,若一連發送10個探測報文段仍然沒反應,服務器就認為客戶端出了故障,接著就關閉連接,
TCP依靠哪些機制來保證可靠傳輸?
-
校驗和:
TCP通過校驗和檢測資料在傳輸程序中是否發生改變,如果收到的報文段的校驗和有差錯,報文段將被丟棄, -
序列號和確認應答:
TCP給發送的每一個報文段中都有序號欄位,每次接收方收到資料后,都會對傳輸方進行確認應答,即發送確認報文段(ACK),其中的確認號告訴發送方成功接收了哪些資料以及下一次的資料從哪里開始發,除此之外,接收方可以根據序列號對資料包進行排序,把有序資料傳送給應用層,并丟棄重復的資料, -
超時重傳:當
TCP發出一個報文段后,它將啟動一個定時器,等待接收端發回的確認,如果超過定時器超時還沒有收到確認,發送方將重發這個報文段, -
約定最大報文段長度(MSS):在建立
TCP連接的時候,雙方約定最大報文段長度作為發送的單位,理想的情況下是該長度的資料剛好不被網路層分片, -
流量控制:
TCP通過滑動視窗機制實作流量控制,視窗(緩沖區)的大小就是發送方在無需等待確認報文段的情況下還能發送的最大資料量,TCP通過視窗大小來協調端對端的發送速度,確保接收端來得及接收,從而盡可能減少丟包, -
擁塞控制:通過擁塞控制演算法(慢開始、擁塞避免、快重傳、快恢復),根據全域網路的擁塞程度來調整擁塞視窗的大小,改善網路擁塞程度,從而盡可能減少丟包,
備注:發送視窗的大小等于Min(接收視窗, 擁塞視窗),因此是兩種流量控制和擁塞控制的共同作用,
ARQ協議與滑動視窗機制的關系?
自動重傳請求 ( Automatic Repeat-reQuest , ARQ)是 OSI模型 中 資料鏈路層 和 傳輸層 的錯誤糾正協議之一,其利用確認和超時這兩個機制,可以在不可靠服務的基礎上實作可靠的資訊傳輸,ARQ協議分等停ARQ協議和連續ARQ協議,連續ARQ協議采用了滑動視窗機制,后者又可分為后退N步協議和選擇重傳協議,
擁塞控制有哪些演算法?
擁塞控制演算法:慢開始、擁塞避免、快重傳、快恢復,這些演算法會根據網路不同的擁塞狀況來搭配使用,
慢開始演算法:在一開始不清楚網路擁塞程度時,避免一開始就向網路中注入大量資料,由小到大逐漸增大擁塞視窗數值,cwnd(擁塞視窗) 初始值設為為 1,每經過一個傳輸輪次(transmission round),cwnd 加倍,(慢開始并不是指cwnd增長慢),當擁塞視窗達到慢開始門限值 ssthresh,改用擁塞避免演算法,(當cwnd = ssthresh時,既可使用慢開始演算法,也可使用擁塞避免演算法),

擁塞避免演算法: 擁塞避免演算法的思路是讓 cwnd緩慢地增大,即每經過一個往返時間 RTT就把發送方的擁塞視窗 cwnd加1,而不是加倍,這樣,擁塞視窗 cwnd按線性規律緩慢增長,比慢開始演算法的擁塞視窗增長速率緩慢得多,
無論在慢開始階段還是在擁塞避免階段,只要發送方判斷網路出現擁塞(計時器超時,未收到確認),就要把慢開始門限 ssthresh設定為出現擁塞時的發送視窗值的一半(但不能小于2),然后把擁塞視窗 cwnd 重新設定為 1,執行慢開始演算法,

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

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

流量控制與擁塞控制有何不同?
流量控制:采用端對端的機制,接收端通過視窗欄位告知發送端自己的接收能力,進而協調發送端的發送速度,避免接收端來不及接收而丟包,
擁塞控制:采用面向全域的機制,根據網路的擁塞程度來改變擁塞視窗,進而協調主機向網路中注入資料的速度,改善網路擁塞程度,從而盡可能減少丟包,
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粘包的原因?
-
發送方原因
TCP默認使用Nagle演算法,當應用層交付給TCP發送的資料包過于小時,發送方會收集了多個較小的資料包進行合并發送,這將會發生粘包, -
接收方原因
TCP發送方發送資料很快,接收方TCP緩沖區收到大量資料,但應用層取出資料的速度又太慢,造成多個資料包被快取,應用層就有可能讀取到多個首尾相接粘到一起的資料包,
什么時候需要處理粘包問題?
- 如果發送方發送的多個資料包本來就是同一塊資料的不同部分就不需要處理粘包現象,
- 如果多個資料包毫不相干,甚至是并列關系,那么這個時候就一定要處理粘包現象了,
如何處理粘包問題?
在應用層進行處理,如:
- 在應用層交給
TCP的每個資料包頭部都添加長度欄位,接收方應用層讀取資料時根據資料包頭部長度欄位回圈讀取相應長度的內容; - 將應用層交給
TCP的每個資料包的首、尾分別添加開始符、結束符,
HTTP(應用層)
HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用于從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議,HTTP是一個基于TCP/IP通信協議來傳遞資料(HTML,圖片等檔案,以及查詢結果等),
主要特點如下:
-
簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑,請求方法常用的有
GET、HEAD、POST,每種方法規定了客戶與服務器聯系的型別不同,由于HTTP協議簡單,使得HTTP服務器的程式規模小,因而通信速度很快, -
靈活:
HTTP允許傳輸任意型別的資料物件,正在傳輸的型別由Content-Type加以標記, -
無連接:無連接的含義是限制每次連接只處理一個請求,服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接,采用這種方式可以節省傳輸時間,
-
無狀態:
HTTP協議是無狀態協議,無狀態是指協議對于事務處理沒有記憶能力,缺少狀態意味著如果后續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連接傳送的資料量增大,另一方面,在服務器不需要先前資訊時它的應答就較快, -
支持
B/S及C/S模式
HTTP 協議由哪幾部分組成?
-
請求協議資訊由 4 部分組成:請求行、請求頭、空行、請求體
-
回應協議資訊也由 4 部分組成:狀態行、回應頭、空行、回應體
使用
curl命令查看協議詳情:
HTTP狀態碼?
HTTP狀態碼由三個十進制數字組成,第一個數字定義了狀態碼的型別,HTTP 狀態碼共有 5 種型別:1xx, 2xx, 3xx, 4xx, 5xx,型別解釋以及部分常見狀態碼如下:
-
1XX (Informational): 接收的請求正在處理100 Continue:表明請求到目前為止都處理的很正常,客戶端可以繼續發送請求或者忽略這個回應, -
2XX (Success): 請求正常處理完畢200 OK: 表示成功處理了請求, -
3XX (Redirection): 需要進行附加操作以完成請求301 Moved Permanently:永久性重定向,302 Found:臨時性重定向, -
4XX (Client Error): 服務器無法處理請求403 Forbidden:請求被服務器拒絕,404 Not Found: 服務器找不到請求的網頁, -
5XX (Server Error): 服務器處理請求出錯500 Internal Server Error:服務器正在執行請求時發生錯誤,
狀態碼 301 和 302 的區別?
301和302狀態碼都表示重定向,就是說瀏覽器在拿到服務器回傳的這個狀態碼后會自動跳轉到一個新的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新增了:PUT、PATCH、DELETE、CONNECT、OPTIONS、TRACE共5種HTTP請求方法,
| 方法 | 描述 |
|---|---|
| PUT | 用于將資料提交至服務器以更新之前存在的資源, |
| PATCH | 是對 PUT 方法的補充,用來對已知資源進行區域更新;當資源不存在時,PATCH會創建一個新的資源, |
| DELETE | 請求服務器洗掉指定的資源, |
| CONNECT | HTTP/1.1 協議中預留給能夠將連接改為管道方式的代理服務器, |
| OPTIONS | 請求服務器告知其支持的各種功能, |
| TRACE | 請求服務器回顯其收到的請求,主要用于測驗或診斷, |
備注:HTTP規范定義了以上方法的行為,但實際開發中可以不遵守,例如:在GET請求對應的介面中去更新資源,將會給自己帶來麻煩,
HTTP冪等性了解嗎?
在編程領域,對于同一個系統,在同樣條件下,一次請求和重復多次請求對服端資源的影響是一致的,就稱該操作為冪等的,
HTTP常見冪等方法:GET、PUT、DELETE、
HTTP常見非冪等方法:POST、PATCH
解釋:
PUT:第一次和第N次請求對服務端資源的影響是相同的,所以是冪等的,例如將id為1234的賬戶金額改為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
GET 和 POST 的區別?
- 從功能上講,
GET一般用來從服務器上獲取資源,POST一般用來在服務器上新增資源; - 從
REST服務角度上說,GET是冪等的,而POST不是冪等的; - 從請求引數形式上看,
GET請求的資料會附在URL之后,POST請求會把提交的資料放置在是HTTP請求報文的請求體中; - 就安全性而言,
POST的安全性要比GET的安全性高,因為 GET 請求提交的資料將明文出現在URL上,而且POST請求引數則被包裝到請求體中,相對更安全; - 從請求的大小看,
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頭域來區分,
HTTP2 的變化:
二進制:HTTP1.X (頭資訊肯定是文本(ASCII編碼),資料體可以是文本,也可以是二進制)的協議決議是基于文本格式,而HTTP2(頭資訊和資料體都是二進制,并且統稱為"幀"(frame):頭資訊幀和資料幀)的協議決議是二進制格式,決議更加高效,
多路復用(Mutiplexing) : 可以復用TCP連接,在一個連接里,客戶端和瀏覽器都可以同時發送多個請求或回應,而且不用按照順序一一對應,這樣就避免了"隊頭堵塞"
header壓縮: HTTP1.X 協議不帶有狀態,每次請求都必須附上所有資訊,所以,請求的很多欄位都是重復的,比如Cookie和User Agent,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度,HTTP2對這一點做了優化,引入了頭資訊壓碩訓制(header compression),一方面,頭資訊使用gzip或compress壓縮后再發送;另一方面,客戶端和服務器同時維護一張“首部表”來跟蹤和存盤之前發送的頭域(鍵-值對),對于不變的域,不再通過每次請求和回應發送;通信期間幾乎不會改變的通用域鍵(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 步:
- 客戶端向服務器發起
HTTPS請求,連接到服務器的443埠, - 服務器將自己向
CA申請的數字證書發送給客戶端,數字證書包含了公鑰、簽名等資訊, - 客戶端決議證書并對其進行驗證,如果證書不是可信機構頒布,或者證書中的域名與實際域名不一 致,或者證書已經過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通信, 如果證書沒有問題,客戶端就會從服務器證書中取出服務器的公鑰,然后客戶端還會生成一個隨機碼
KEY,并使用公鑰將其加密,隨后客戶端把加密后的隨機碼KEY發送給服務器,作為后面對稱加密的密鑰, - 服務器在收到訊息后使用私鑰解密得到隨機碼
KEY,到此客戶端和服務器就已經成功建立了安全連接,接下來就可以用對稱加密進行通信了,
Cookie是什么?
HTTP Cookie(也叫 Web Cookie或瀏覽器 Cookie)是服務器發送到用戶瀏覽器并保存在本地的一小塊資料,它會在瀏覽器下次向同一服務器再發起請求時被攜帶并發送到服務器上,通常可以用于個性化設定,瀏覽器行為跟蹤,
Session是什么?
由于HTTP協議是無狀態的協議,所以服務器需要記錄用戶狀態時就需要借助Session機制,目前Session常見實作要借助Cookie,即服務器端創建一個Session物件,同時會創建一個特殊的Cookie物件(name為"JSESSIONID",value為Session物件的ID),然后將該Cookie物件發送至瀏覽器,當瀏覽器端發送第N(N>1)次請求到同一服務器時就會攜帶該name為JSESSIONID的Cookie物件,服務器根據name為JSESSIONID的Cookie的value(sessionId)去查詢對應Session物件,從而區分不同用戶,(Session物件默認存活30分鐘)
Cookie和Session的區別?
- 作用范圍不同,
Cookie保存在客戶端(瀏覽器),Session保存在服務器端, - 存取方式的不同,
Cookie只能保存ASCII編碼的字符,Session可以存任意資料型別,一般情況下我們可以在Session中保持一些常用變數資訊,比如說商品ID,商品數量(購物車場景)等, - 有效期不同,
Cookie可設定為長時間保持,比如我們經常使用的默認登錄功能,Session一般失效時間較短,客戶端關倍訓者Session超時都會失效(Session物件默認存活30分鐘), - 隱私策略不同,
Cookie存盤在客戶端,比較容易遭到不法獲取,早期有人將用戶的登錄名和密碼 存盤在Cookie中導致資訊被竊取;Session存盤在服務端,安全性相對Cookie要好一些, - 存盤大小不同, 單個
Cookie保存的資料量<= 4KB;對于Session來說并沒有上限,但出于對服務器端的性能考慮,Session內不要存放過多的東西,并且應設定Session洗掉機制,
在瀏覽器中輸入 URL地址到顯示主頁的程序?
- 首先根據
URL進行域名決議,得到對應IP地址,決議時,首先查看瀏覽器DNS快取是否命中,沒有的話再查看作業系統DNS快取(hosts檔案)是否命中,如果再沒有命中就會借助域名服務器進行決議, - 位于應用層瀏覽器的封裝好
HTTP請求報文后交給應用層的TCP協議, TCP協議根據IP地址向服務器的80埠發起三次握手以建立TCP連接,隨后將HTTP報文作為自己的資料部分封裝到TCP報文段中發送出去,- 服務器上的
TCP協議收到TCP報文段后進行拆包得到HTTP請求報文,HTTP請求報文隨后被應用層的服務器程式讀取、決議和處理后,按照之前類似步驟回應資料給瀏覽器, - 瀏覽器得到
HTTP回應報文后進行決議,渲染并顯示給用戶,
計算機分層模型
- OSI 七層模型:大而全,但是比較復雜、而且是先有了理論模型,沒有實際應用,
- TCP/IP 四層模型:是由實際應用發展總結出來的,從實質上講,
TCP/IP只有最上面三層,最下面一 層沒有什么具體內容,TCP/IP參考模型沒有真正描述這一層的實作, - 五層模型:五層模型只出現在計算機網路教學程序中,這是對七層模型和四層模型的一個折中,既 簡潔又能將概念闡述清楚,
三種模型以及對應層次關系如下:

OSI七層網路體系結構各層的主要功能:
-
應用層:為應用程式提供互動服務,在互聯網中的應用層協議很多,如域名系統
DNS,支持萬維網 應用的HTTP協議,支持電子郵件的SMTP協議等, -
表示層:主要負責資料格式的轉換,如加密解密、轉換翻譯、壓縮解壓縮等,
-
會話層:負責在網路中的兩節點之間建立、維持和終止通信,如服務器驗證用戶登錄便是由會話層 完成的,
-
運輸層:有時也譯為傳輸層,向主機行程提供通用的資料傳輸服務,該層主要有以下兩種協議:
-
TCP:提供面向連接的、可靠的資料傳輸服務; -
UDP:提供無連接的、盡最大努力的資料傳輸服務,但不保證資料傳輸的可靠性,
-
-
網路層:選擇合適的路由和交換結點,確保資料及時傳送,主要包括
IP協議, -
資料鏈路層:資料鏈路層通常簡稱為鏈路層,將網路層傳下來的
IP資料包組裝成幀,并再相鄰節點 的鏈路上傳送幀, -
物理層 :實作相鄰節點間位元流的透明傳輸,盡可能屏蔽傳輸介質和通信手段的差異,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/292038.html
標籤:其他
