天天看點

TCP如何保證可靠傳輸

TCP如何保證可靠傳輸

TCP工作c在哪一層、為什麼需要TCP協定?

TCP/IP是一個四層的體系結構,主要包括:應用層、傳輸層、網絡層和網絡接口層。

五層協定的體系結構主要包括:應用層、傳輸層、網絡層,資料鍊路層和實體層。

OSI七層協定模型主要包括是:應用層(Application)、表示層(Presentation)、

會話層(Session)、傳輸層(Transport)、網絡層(Network)、資料鍊路層(Data Link)、實體層(Physical)。

TCP如何保證可靠傳輸

發送端在層與層之間傳輸資料時,每經過一層時會被打上一個該層所屬的首部資訊。反之,接收端在層與層之間傳輸資料時,每經過一層時會把對應的首部資訊去除。

TCP如何保證可靠傳輸

IP 層是不提供可靠性保障的、無狀态的,它不保證網絡包的傳遞、不保證網絡包的按序傳遞、也不保證網絡包中的資料的完整性。如果需要保障網絡資料包的可靠性,那麼就需要由上層(傳輸層)的 TCP 協定來負責。因為 TCP 是一個工作在傳輸層的可靠資料傳輸的服務,它能確定接收端接收的網絡包是無損壞、無間隔、非備援和按序的。

TCP首部

TCP如何保證可靠傳輸
  1. 每個TCP段都包含源端和目的端的端口号,用于尋找發端和收端應用程序。這兩個值加上IP首部中的源端IP位址和目的端IP位址唯一确定一個TCP連接配接。
  2. 序列号用來辨別從TCP發端向TCP收端發送的資料位元組流,它表示在這個封包段中的的第一個資料位元組。如果将位元組流看作在兩個應用程式間的單向流動,則TCP用序列号對每個位元組進行計數。序列号是32 bit的無符号數,序列号到達232-1後又從0開始。用來解決網絡包亂序問題。
  3. 确認應答号包含發送确認的一端所期望收到的下一個序号。是以,确認序号應當是上次已成功收到資料位元組序号加1. 用來解決不丢包的問題
  4. 标志比特:ACK:該位為 1 時,「确認應答」的字段變為有效,TCP 規定除了最初建立連接配接時的 SYN 包之外該位必須設定為 1 。RST:該位為 1 時,表示 TCP 連接配接中出現異常必須強制斷開連接配接。SYN:該位為 1 時,表示希望建立連接配接,并在其「序列号」的字段進行序列号初始值的設定。FIN:該位為 1 時,表示今後不會再有資料發送,希望斷開連接配接。當通信結束希望斷開連接配接時,通信雙方的主機之間就可以互相交換 FIN 位為 1 的 TCP 段。

使用WireShark抓包分析三次握手

TCP如何保證可靠傳輸
TCP如何保證可靠傳輸

TCP 建立連接配接為什麼需要三次握手

針對這個問題,首先我們需要知道什麼是連接配接,隻有知道連接配接的定義,我們才能去嘗試回答為什麼 TCP 建立連接配接需要三次握手。什麼是TCP連接配接?用于保證可靠性和流量控制維護的某些狀态資訊,這些資訊的組合,包括Socket、序列号和視窗大小稱為連接配接。是以,重要的是為什麼三次握手才可以初始化Socket、序列号和視窗大小并建立 TCP 連接配接。接下來以三個方面分析三次握手的原因:

  1. 三次握手才可以阻止重複曆史連接配接的初始化(主要原因)
  2. 三次握手才可以同步雙方的初始序列号
  3. 三次握手才可以避免資源浪費
TCP如何保證可靠傳輸

如果用戶端的 SYN 阻塞了,重複發送多次 SYN 封包,那麼伺服器在收到請求後就會建立多個備援的無效連結,造成不必要的資源浪費。

TCP如何保證可靠傳輸

TCP 協定的通信雙方, 都必須維護一個「序列号」, 序列号是可靠傳輸的一個關鍵因素,它的作用:

接收方可以去除重複的資料;接收方可以根據資料包的序列号按序接收;可以辨別發送出去的資料包中, 哪些是已經被對方收到的;

TCP如何保證可靠傳輸

我們都知道 TCP 連接配接建立是需要三次握手,假設攻擊者短時間僞造不同 IP 位址的 SYN 封包,服務端每接收到一個 SYN 封包,就進入SYN_RCVD 狀态,但服務端發送出去的 ACK + SYN 封包,無法得到未知 IP 主機的 ACK 應答,久而久之就會占滿服務端的SYN 接收隊列(未連接配接隊列),使得伺服器不能為正常使用者服務。

TCP如何保證可靠傳輸
TCP如何保證可靠傳輸
TCP如何保證可靠傳輸

為什麼 TIME_WAIT 等待的時間是 2MSL?

  1. 為了保證用戶端最後一次揮手的封包能夠到達伺服器,如果第四次揮手的封包段丢失了,伺服器會逾時重傳這個第三次揮手的封包段,是以用戶端不是直接進入CLOSED,而是要保持TIME_WAIT(等待2MSL就是TIME_WAIT)就起到作用了,當再次收到伺服器的逾時重傳的斷開連接配接的第三次揮手的請求的時候,用戶端會繼續給伺服器發送一個第四次揮手的封包,能夠保證對方(伺服器)收到用戶端的回應封包,最後用戶端和伺服器正确的關閉連接配接。
  2. 如果Client(用戶端)直接CLOSED(關閉),然後又再向Server(伺服器端)發起一個新連接配接,我們不能保證這個新連接配接與剛關閉的連接配接的端口号是不同的。也就是說有可能新連接配接和老連接配接的端口号是相同的。一般來說不會發生什麼問題,但是還是有特殊情況出現:假設新連接配接和已經關閉的老連接配接端口号是一樣的,如果前一次連接配接的某些資料仍然滞留在網絡中,這些延遲資料在建立新連接配接之後才到達Server,由于新連接配接和老連接配接的端口号是一樣的,于是,TCP協定就認為那個延遲的資料是屬于新連接配接的,這樣就和真正的新連接配接的資料包發生混淆了。是以TCP連接配接還要在TIME_WAIT狀态等待2倍MSL,這樣可以保證本次連接配接的所有資料都從網絡中消失。
TCP如何保證可靠傳輸

逾時與重傳

逾時重傳 :在發送資料時,設定一個定時器,當超過指定的時間後,沒有收到對方的 ACK 确認應答封包,就會重發該資料TCP 會在以下兩種情況發生逾時重傳:

  1. 資料包丢失
  2. 确認應答丢失
TCP如何保證可靠傳輸

重傳逾時時間RTO計算

TCP逾時與重傳中最重要的部分就是對一個給定連接配接的往返時間(RTT)的測量。由于路由器和網絡流量均會變化,是以我們認為這個時間可能經常會發生變化,TCP應該跟蹤這些變化并相應地改變其逾時時間。

滑動視窗

TCP如何保證可靠傳輸

win這個字段是接收端告訴發送端自己還有多少緩沖區可以接收資料。于是發送端就可以根據這個接收端的處理能力來發送資料,而不會導緻接收端處理不過來。起到流量控制的作用

TCP如何保證可靠傳輸

可用視窗的大小為 0 時,表明可用視窗耗盡,在沒收到 ACK 确認之前是無法繼續發送資料了。

擁塞控制

前面的流量控制是避免「發送方」的資料填滿「接收方」的緩存,但我們并不知道當時的網絡狀況是怎樣的,在網絡出現擁堵時,如果繼續發送大量資料包,可能會導緻資料包時延、丢失等,這時 TCP 就會重傳資料,但是一重傳就會導緻網絡的負擔更重,于是會導緻更大的延遲以及更多的丢包,這個情況就會進入惡性循環被不斷地放大....

每一個 TCP 連接配接都會維護一個擁塞控制視窗(cwnd),它決定了發送方同時能向接收方發送多少資料,其作用主要有兩個:

  1. 防止發送方向接收方發送了太多資料,導緻接收方無法處理;
  2. 防止 TCP 連接配接的任意一方向網絡中發送大量資料,導緻網絡擁塞崩潰;

使用 TCP 慢啟動時,發送方每收到一個響應方的 ACK 消息,擁塞視窗大小就會加一。當擁塞視窗大小大于慢啟動門檻值時,就會使用擁塞避免算法:

線性增長:每經過一個往返時間 RTT,擁塞視窗大小會加一;積式減少:當發送方發送的資料包丢包時,慢啟動門檻值會設定為擁塞視窗大小的一半;

慢啟動為發送方的TCP增加了另一個視窗:擁塞視窗(congestion window),記為cwnd。當與另一個網絡的主機建立TCP連接配接時,擁塞視窗被初始化為1個封包段(即另一端通告的封包段大小)。每收到一個ACK,擁塞視窗就增加一個封包段(cwnd以位元組為機關,但是慢啟動以封包段大小為機關進行增加)。發送方取擁塞視窗與通告視窗中的最小值作為發送上限。擁塞視窗是發送方使用的流量控制,而通告視窗則是接收方使用的流量控制。

TCP如何保證可靠傳輸
TCP如何保證可靠傳輸

當cwnd超過一定的閥值,就會啟動擁塞避免算法.

TCP如何保證可靠傳輸

網絡就會慢慢進入了擁塞的狀況了,于是就會出現丢包現象,這時就需要對丢失的資料包進行重傳。當觸發了重傳機制,也就進入了「擁塞發生算法」。當網絡出現擁塞,也就是會發生資料包重傳,重傳機制主要有兩種:

  1. 逾時重傳
  2. 快速重傳當發生了「逾時重傳」,則就會使用擁塞發生算法。這個時候,ssthresh 和 cwnd 的值會發生變化:ssthresh 設為 cwnd/2,cwnd 重置為 1
TCP如何保證可靠傳輸