必知必會的TCP

一、概述

1、TCP的特點

  • 面向連接: 使用TCP傳輸數據必須先建立連接,傳輸完成之後再釋放鏈接
  • 面向字節流:數據以流的形式進行傳輸
  • 全雙工通信:建立TCP連接後,通信雙方都能發送數據
  • 可靠:通過TCP連接傳送的數據不丟失、無差錯、不重複、按順序到達

2、tcp的可靠性如何保證

  • 分塊傳送:數據被分割成最合適的數據塊(UDP的數據報長度不變)
  • 等待確認:通過定時器等待接收端發送確認請求,收不到確認則重發
  • 確認回覆:收到確認後發送確認回覆(不是立即發送,通常推遲幾分之一秒)
  • 數據校驗:保持首部和數據的校驗和,檢測數據傳輸過程有無變化
  • 亂序排序:接收端能重排序數據,以正確的順序交給應用端
  • 重複丟棄:接收端能丟棄重複的數據包
  • 流量緩衝:兩端有固定大小的緩衝區(滑動窗口),防止速度不匹配丟數據

3、報文段格式

  • TCP雖面向字節流,但傳送的數據單元 = 報文段
  • 報文段 = 首部 + 數據 2部分
  • TCP的全部功能體現在它首部中各字段的作用,故下面主要講解TCP報文段的首部
  1. 首部前20個字符固定、後面有4n個字節是根據需而增加的選項
  2. 故 TCP首部最小長度 = 20字節

3.1、宏觀位置

  • TCP數據被封裝在IP數據報中

3.2、首部格式

  1. 第1-2兩個字節:源端口號
  2. 第3-4兩個字節:目的端口號

源端口號+ip首部中的源ip地址+目的端口號+ip首部中的目的ip地址,唯一的確定了一個tcp連接。

  1. 第5-8四個字節:32位序號。tcp提供全雙工服務,兩端都有各自的序號。解決網絡包亂序的問題
  2. 第9-12四個字節:32位確認序列號。上次成功收到數據字節序號加1,ack爲1纔有效。解決丟包的問題

這兩個字段是TCP可靠傳輸服務的關鍵部分,序列號是該報文段首字節的字節流編號(TCP把數據看成是有序的字節流,TCP隱式地對數據流的每個字節進行編號)。這樣理解可能更直觀,當報文被分解成多個報文段時,序列號就是報文段首字節在整個報文的偏移量。確定號指定下一個期待的字節。

  1. 第13個字節:數據偏移/首部長度

4位頭部長度(header length):由於首部可能含有可選項內容,因此TCP報頭的長度是不確定的,報頭不包含任何任選字段則長度爲20字節,4位首部長度字段所能表示的最大值爲1111,轉化爲10進製爲15,15*4 = 60,故報頭最大長度爲60字節。首部長度也叫數據偏移,是因爲首部長度實際上指示了數據區在報文段中的起始偏移值。

  1. 後面6bite:保留(6位):爲將來定義新的用途保留,現在一般置0。
  2. 隨後6bite:控制位:URG、 ACK、PSH 、 RST 、 SYN、 FIN
  3. 第15-16兩個字節:窗口大小。接收端期望接收的字節數。解決流量控制的問題

是TCP流量控制的一個手段。這裏說的窗口,指的是接收通告窗口(Receiver Window,RWND)。它告訴對方本端的TCP接收緩衝區還能容納多少字節的數據,這樣對方就可以控制發送數據的速度,從而達到流量控制。窗口大小爲一個16bit字段,因而窗口大小最大爲65535。

  1. 第17-18兩個字節:校驗和。由發送端計算和存儲,由接收端校驗。解決數據正確性問題

16位校驗和(TCP check sum):由發送端填充,接收端對TCP報文段執行CRC算法以檢驗TCP報文段在傳輸過程中是否損壞。注意,這個校驗不僅包括TCP頭部,也包括數據部分。這也是TCP可靠傳輸的一個重要保障。

  1. 第19-20兩個字節:緊急指針

只有當 URG 標誌置 1 時緊急指針纔有效。緊急指針是一個正的偏移量,和順序號字段中的值相加表示緊急數據最後一個字節的序號。 TCP 的緊急方式是發送端向另一端發送緊急數據的一種方式。

3.3、標識位說明

  1. URG:緊急指針標誌,爲1時表示緊急指針有效,該報文應該優先傳送,爲0則忽略緊急指針。
  2. ACK:確認序號標誌,爲1時表示確認號有效,爲0表示報文中不含確認信息,忽略確認號字段。我們稱攜帶ACK標識的TCP報文段爲確認報文段。
  3. PSH:push標誌,爲1表示是帶有push標誌的數據,指示接收方在接收到該報文段以後,應優先將這個報文段交給應用程序,而不是在緩衝區排隊。
  4. RST:重置連接標誌,用於重置由於主機崩潰或其他原因而出現錯誤的連接。或者用於拒絕非法的報文段和拒絕連接請求。我們稱攜帶RST標誌的TCP報文段爲復位報文段。
  5. SYN:表示請求建立一個連接。在連接請求中,SYN=1和ACK=0表示該數據段沒有使用捎帶的確認域,而連接應答捎帶一個確認,即SYN=1和ACK=1。我們稱攜帶SYN標誌的TCP報文段爲同步報文段。
  6. FIN:finish標誌,用於釋放連接,爲1時表示發送方已經沒有數據發送了,即關閉本方數據流。我們稱攜帶FIN標誌的TCP報文段爲結束報文段。

二、連接的建立與釋放

1、TCP建立連接

  • TCP建立連接需三次握手
  • 具體介紹如下:

  • 第一次握手

客戶端向服務器發送一個連接請求的報文段。

同步標誌位設爲1:SYN=1;

隨機選擇一個起始序號:seq=x;

不攜帶數據(因SYN位被設置爲1的報文段不能攜帶數據,但是要消耗一個序號);

客戶端進入同步已發送狀態(SYN_SEND);

等待客戶端的確認。

  • 第二次握手

服務器收到請求連接報文段後,若同意連接,則向客戶端發回連接確認的報文段。(爲該TCP連接分配TCP緩存,變量)

同步標誌位設爲1:SYN=1;

確認標誌位設爲1:ACK=1;

隨機選擇一個起始序號:seq=y;

確認號字段設爲:ack=x+1;

不攜帶數據(因SYN位被設置爲1的報文段不能攜帶數據,但是要消耗一個序號);

服務端進入同步已接受狀態(SYN_RCVD)

  • 第三次握手

客戶端收到確認報文段後,向服務端再次發送連接確認報文段。(爲該TCP連接分配TCP緩存,變量)

確認標誌位設爲1:ACK=1;

序號:seq=x+1;

確認號字段:ack=y+1;

可攜帶數據(因SYN位未被設置爲1,若不攜帶數據不消耗序號)

客戶端、服務器都進入已創建狀態

1.1、爲什麼要三次握手

三次握手的目的是建立可靠的通信信道,說到通訊,簡單來說就是數據的發送與接收,而三次握手最主要的目的就是雙方確認自己與對方的發送與接收是正常的。

第一次握手:Client 什麼都不能確認;Server 確認了對方發送正常,自己接收正常

第二次握手:Client 確認了:自己發送、接收正常,對方發送、接收正常;Server 確認了:對方發送正常,自己接收正常

第三次握手:Client 確認了:自己發送、接收正常,對方發送、接收正常;Server 確認了:自己發送、接收正常,對方發送、接收正常

所以三次握手就能確認雙發收發功能都正常,缺一不可。

1.2、第 2 次握手傳回了 ACK,爲什麼還要傳回 SYN?

接收端傳回發送端所發送的 ACK 是爲了告訴客戶端,我接收到的信息確實就是你所發送的信號了,這表明從客戶端到服務端的通信是正常的。而回傳 SYN 則是爲了建立並確認從服務端到客戶端的通信

2、連接釋放過程

  • 第一次揮手

客戶端向服務器發送一個連接釋放的報文段。

終止控制位設爲1:FIN=1;

報文段序號,設爲前面已經傳送過來的數據的最後一個字節的序號加1:seq=u;

可攜帶數據,(FIN報文段即使不攜帶數據,也要消耗一個序號)

客戶端進入FIN-WAIT-1(終止等待1)狀態。

  • 第二次揮手

服務器收到客戶端的連接釋放報文段後,則向客戶端發回連接釋放確認的報文段。

確認標誌位設爲1:ACK=1;

報文段序號,設爲前面已經傳送過來的數據的最後一個字節的序號加1:seq=u;

確認號字段設爲:ack=u+1;

服務端就進入了CLOSE-WAIT(關閉等待)狀態;

客戶端->服務端已斷開,服務端->客戶端還未斷開

  • 第三次揮手

若服務器已沒有要向客戶端發送的數據,則發出釋放連接的報文段。

終止控制位設爲1:FIN=1;

確認標誌位設爲1:ACK=1;

報文段序號:seq=w;

重複上次已發送的確認號字段 設爲:ack=u+1;

可攜帶數據,(FIN報文段即使不攜帶數據,也要消耗一個序號)

服務端進入最後確認狀態(LAST-ACK)

  • 第四次揮手

客戶端收到釋放連接的報文段後,則向服務器發回連接釋放確認的報文段。

確認標誌位設爲1:ACK=1;

報文段序號:seq=u+1;

確認號字段設爲:ack=w+1;

可攜帶數據,(FIN報文段即使不攜帶數據,也要消耗一個序號)

客戶端就進入了TIME-WAIT(時間等待)狀態,服務器進入CLOSED狀態;

注意此時TCP連接還沒有釋放,必須經過2∗MSL(最長報文段壽命)的時間後,當客戶端撤銷相應的TCB後,才進入CLOSED狀態。

3.1、爲什麼客戶端最後還要等待2MSL?

MSL(Maximum Segment Lifetime),TCP允許不同的實現可以設置不同的MSL值。

第一,保證客戶端發送的最後一個ACK報文能夠到達服務器,因爲這個ACK報文可能丟失,站在服務器的角度看來,我已經發送了FIN+ACK報文請求斷開了,客戶端還沒有給我回應,應該是我發送的請求斷開報文它沒有收到,於是服務器又會重新發送一次,而客戶端就能在這個2MSL時間段內收到這個重傳的報文,接着給出迴應報文,並且會重啓2MSL計時器。

第二,防止類似與“三次握手”中提到了的“已經失效的連接請求報文段”出現在本連接中。客戶端發送完最後一個確認報文後,在這個2MSL時間中,就可以使本連接持續的時間內所產生的所有報文段都從網絡中消失。這樣新的連接中不會出現舊連接的請求報文。

3.2、爲什麼建立連接是三次握手,關閉連接確是四次揮手呢?

建立連接的時候, 服務器在LISTEN狀態下,收到建立連接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端。

而關閉連接時,服務器收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,而自己也未必全部數據都發送給對方了,所以己方可以立即關閉,也可以發送一些數據給對方後,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會分開發送,從而導致多了一次。

三、TCP 協議如何保證可靠傳輸

  • 應用數據被分割成 TCP 認爲最適合發送的數據塊。
  • TCP 給發送的每一個包進行編號,接收方對數據包進行排序,把有序數據傳送給應用層。
  • 校驗和: TCP 將保持它首部和數據的檢驗和。這是一個端到端的檢驗和,目的是檢測數據在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP 將丟棄這個報文段和不確認收到此報文段。
  • TCP 的接收端會丟棄重複的數據。
  • 流量控制: TCP 連接的每一方都有固定大小的緩衝空間,TCP 的接收端只允許發送端發送接收端緩衝區能接納的數據。當接收方來不及處理髮送方的數據,能提示發送方降低發送的速率,防止包丟失。TCP 使用的流量控制協議是可變大小的滑動窗口協議。 (TCP 利用滑動窗口實現流量控制)
  • 擁塞控制: 當網絡擁塞時,減少數據的發送。
  • ARQ 協議: 也是爲了實現可靠傳輸的,它的基本原理就是每發完一個分組就停止發送,等待對方確認。在收到確認後再發下一個分組。
  • 超時重傳: 當 TCP 發出一個段後,它啓動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段

1、ARQ 協議

自動重傳請求(Automatic Repeat-reQuest,ARQ)是 OSI 模型中數據鏈路層和傳輸層的錯誤糾正協議之一。它通過使用確認和超時這兩個機制,在不可靠服務的基礎上實現可靠的信息傳輸。如果發送方在發送後一段時間之內沒有收到確認幀,它通常會重新發送。ARQ 包括停止等待 ARQ 協議和連續 ARQ 協議。

停止等待 ARQ 協議

停止等待協議是爲了實現可靠傳輸的,它的基本原理就是每發完一個分組就停止發送,等待對方確認(回覆 ACK)。如果過了一段時間(超時時間後),還是沒有收到 ACK 確認,說明沒有發送成功,需要重新發送,直到收到確認後再發下一個分組。

在停止等待協議中,若接收方收到重複分組,就丟棄該分組,但同時還要發送確認。

優缺點:

  • 優點: 簡單
  • 缺點: 信道利用率低,等待時間長

連續 ARQ 協議

連續 ARQ 協議可提高信道利用率。發送方維持一個發送窗口,凡位於發送窗口內的分組可以連續發送出去,而不需要等待對方確認。接收方一般採用累積確認,對按序到達的最後一個分組發送確認,表明到這個分組爲止的所有分組都已經正確收到了。

優缺點:

  • 優點: 信道利用率高,容易實現,即使確認丟失,也不必重傳。
  • 缺點: 不能向發送方反映出接收方已經正確收到的所有分組的信息。 比如:發送方發送了 5 條 消息,中間第三條丟失(3 號),這時接收方只能對前兩個發送確認。發送方無法知道後三個分組的下落,而只好把後三個全部重傳一次。這也叫 Go-Back-N(回退 N),表示需要退回來重傳已經發送過的 N 個消息。

2、滑動窗口和流量控制

滑動窗口包含發送窗口接收窗口:

發送窗口:任意時刻,發送方維護的一組連續的、允許發送幀的幀序號;

接收窗口:任意時刻,接收方維護的一組連續的、允許接收幀的幀序號;

滑動窗口工作原理 對於發送端:

  1. 每收到一個確認幀,發送窗口就向前滑動一個幀的距離
  2. 當發送窗口內無可發送的幀時(即窗口內的幀全部是已發送但未收到確認的幀),發送方就會停止發送,直到收到接收方發送的確認幀使窗口移動,窗口內有可以發送的幀,之後纔開始繼續發送

對於接收端:當收到數據幀後,將窗口向前移動一個位置,併發回確認幀,若收到的數據幀落在接收窗口之外,則一律丟棄。

TCP 利用滑動窗口實現流量控制。流量控制是爲了控制發送方發送速率,保證接收方來得及接收。 接收方發送的確認報文中的窗口字段可以用來控制發送方窗口大小,從而影響發送方的發送速率。將窗口字段設置爲 0,則發送方不能發送數據

3、擁塞控制

在某段時間,若對網絡中某一資源的需求超過了該資源所能提供的可用部分,網絡的性能就要變壞。這種情況就叫擁塞。擁塞控制就是爲了防止過多的數據注入到網絡中,這樣就可以使網絡中的路由器或鏈路不致過載。擁塞控制所要做的都有一個前提,就是網絡能夠承受現有的網絡負荷。擁塞控制是一個全局性的過程,涉及到所有的主機,所有的路由器,以及與降低網絡傳輸性能有關的所有因素。相反,流量控制往往是點對點通信量的控制,是個端到端的問題。流量控制所要做到的就是抑制發送端發送數據的速率,以便使接收端來得及接收。

爲了進行擁塞控制,TCP 發送方要維持一個 擁塞窗口(cwnd) 的狀態變量。擁塞控制窗口的大小取決於網絡的擁塞程度,並且動態變化。發送方讓自己的發送窗口取爲擁塞窗口和接收方的接受窗口中較小的一個。

TCP 的擁塞控制採用了四種算法,即 慢開始擁塞避免快重傳快恢復。在網絡層也可以使路由器採用適當的分組丟棄策略(如主動隊列管理 AQM),以減少網絡擁塞的發生。

  • 慢開始: 慢開始算法的思路是當主機開始發送數據時,如果立即把大量數據字節注入到網絡,那麼可能會引起網絡阻塞,因爲現在還不知道網絡的符合情況。經驗表明,較好的方法是先探測一下,即由小到大逐漸增大發送窗口,也就是由小到大逐漸增大擁塞窗口數值。cwnd 初始值爲 1,每經過一個傳播輪次,cwnd 加倍。
  • 擁塞避免: 擁塞避免算法的思路是讓擁塞窗口 cwnd 緩慢增大,即每經過一個往返時間 RTT 就把發送放的 cwnd 加 1.
  • 快重傳與快恢復: 在 TCP/IP 中,快速重傳和恢復(fast retransmit and recovery,FRR)是一種擁塞控制算法,它能快速恢復丟失的數據包。沒有 FRR,如果數據包丟失了,TCP 將會使用定時器來要求傳輸暫停。在暫停的這段時間內,沒有新的或複製的數據包被髮送。有了 FRR,如果接收機接收到一個不按順序的數據段,它會立即給發送機發送一個重複確認。如果發送機接收到三個重複確認,它會假定確認件指出的數據段丟失了,並立即重傳這些丟失的數據段。有了 FRR,就不會因爲重傳時要求的暫停被耽誤。 當有單獨的數據包丟失時,快速重傳和恢復(FRR)能最有效地工作。當有多個數據信息包在某一段很短的時間內丟失時,它則不能很有效地工作。

四、TCP, UDP 協議的區別

  • UDP 在傳送數據之前不需要先建立連接,遠地主機在收到 UDP 報文後,不需要給出任何確認。雖然 UDP 不提供可靠交付,但在某些情況下 UDP 卻是一種最有效的工作方式(一般用於即時通信),比如: QQ 語音、 QQ 視頻 、直播等等

  • TCP 提供面向連接的服務。在傳送數據之前必須先建立連接,數據傳送結束後要釋放連接。 TCP 不提供廣播或多播服務。由於 TCP 要提供可靠的,面向連接的傳輸服務(TCP 的可靠體現在 TCP 在傳遞數據之前,會有三次握手來建立連接,而且在數據傳遞時,有確認、窗口、重傳、擁塞控制機制,在數據傳完後,還會斷開連接用來節約系統資源),這難以避免增加了許多開銷,如確認,流量控制,計時器以及連接管理等。這不僅使協議數據單元的首部增大很多,還要佔用許多處理機資源。TCP 一般用於文件傳輸、發送和接收郵件、遠程登錄等場景。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章