【計算機網絡】傳輸層 - TCP協議

特點

  • 面向連接, 使用TCP傳輸數據前必須建立連接,完畢後須釋放連接。
  • 點對點, 每個TCP連接只能有兩個端點。
  • 可靠傳輸, 通過TCP的超時重傳和捎帶確認機制保證傳輸的數據能夠按序正確到達。
  • 流量控制和擁塞控制,在網絡情況較差時可控制傳輸速率。
  • 雙工通信, TCP連接的兩端都設有發送緩存和接收緩存, 會在合適的時機處理數據。
  • 面向字節流, TCP流指流入到進程或從進程流出的字節序列,TCP吧應用程序交下來的數據堪稱是一串連續的字節流處理。

socket套接字

TCP把連接作爲最基本的抽象,因此每一條連接都需要有兩個端點,而套接字(socket)就是TCP連接的端點。

格式
套接字 socket = (IP地址 : 端口號)

每一條TCP連接唯一地被兩個套接字確定。

同一個IP地址可以有不同的TCP連接, 同一個端口號也可有不同的TCP連接。

注:
socket也指操作系統提供的一套應用編程接口 API。
由於TCP/IP的核心內容被封裝在操作系統中,如果應用程序要使用TCP/IP,則需要使用操作系統提供的socket API來實現。

TCP報文

在這裏插入圖片描述

  • 源端口和目的端口 各2字節

用來寫入源端口號和目的端口號。

  • 序號 4字節

4字節共2^ 32個序號。序號增加到 2^32 - 1 (32個1)後又回到0。
用來爲字節流中的每一個字節都按序編號,序號在連接建立時設置。
首部中的序號表示該數據報中發送的第一個字節的序號。

  • 確認號 4字節

表示期望收到對方下一個報文段的數據的第一個字節的序號。例如A向B發送了序號爲300,長度爲100的數據報,B期望繼續接受數據,則需要將發送給A的確認報文中把確認號設置爲401。

  • 數據偏移 4位

指出TCP報文段首部的長度。 因爲首部中還有長度不確定的選項字段, 因此需要額外用數據偏移字段記錄首部的長度。

數據偏移字段單位爲32bit(4字節)。 4位能表示最大二進制數爲15, 因此該字段最大能表示60字節,這也是TCP首部的最大長度。

  • 保留 6位

6個控制位

  • 緊急URG 1位

URG = 1 時表示緊急指針字段有效。它告訴系統次報文中有緊急數據,應當儘快傳送,而不按原來的排隊順序傳送。

  • 確認ACK 1位

當ADC = 1時確認號字段纔有效, 在TCP連接建立後所有傳送的報文都必須把ACK設爲1.

  • 推送PSH1位

PSH = 1表示推送操作, 立即創建一個表文段發送出去, 接收方TCP收到PSH = 1的報文段時就儘快的交付給接收應用進程。

  • 復位RST1位

當RST = 1 時,表明TCP連接中出現嚴重差錯,必須釋放連接,然後重新建立連接。 它還用來拒絕非法的報文段或拒絕打開一個連接。

  • 同步SYN1位

在建立連接時用來同步序號。
當SYN = 1 且 ACK = 0時 表明這是一個連接請求報文段。 對方若同意連接, 則應在響應的報文段中使SYN = 1 和 ACK = 1,。

  • 終止FIN1位

FIN = 1是表示發送方的數據發送完畢, 將要釋放連接。

窗口 2字節

最大 2^16 - 1, 接受方的緩存大小有限, 所以需要使用該字段表示發送方的接收窗口大小。

窗口值經常在動態變化着.

  • 校驗和2字節

校驗範圍包括首部和數據這兩部分. 和UDP一樣需要加僞首部.

  • 緊急指針 2字節

指出本報文段中的緊急數據的字節數.

  • 選項
    長度可變, 最長可達40字節, 沒有選項時首部長20字節,

TCP連接建立

三次握手

在這裏插入圖片描述

A爲客戶端, B爲服務器, 最初二者都爲CLOSE關閉狀態。

B服務器進程先創建TCB(Transmission Control Block)傳輸控制塊, 進入Listen狀態準備接受客戶進程的連接請求。

  1. 客戶端A創建TCB, 然後向客戶端發送請求報文, 其中SYN = 1, 表示建立連接信號有效, ACK = 0 , 因爲是第一次請求還沒有確認號所以確認信號無效,seq = x 設置一個初始序號。 TCP規定SYN = 1 的報文不能攜帶數據, 但要消耗一個序列號。 發送完成後A客戶端進入SYN-SENT狀態。
  2. 服務器B收到A的連接請求後,如同意連接則需要向A發送確認,使 SYN = 1,表示連接請求, ACK = 1 , 因爲已經收到了A的seq序號, 將要請求下一個序號,所以ACK生效, 並且確認號ack = x + 1。
    同時B還要帶上自己設置的初始序號seq = y。 發送完成後B服務端進入SYN-RCVD。
  3. 客戶端A收到服務端B的確認後, 需要再向服務端B發送一個確認。 設置seq = x + 1,ACK = 1, 確認號ack = y + 1(SYN = 0),向B進行確認。 發送後A進入ESTABLISHED狀態。服務端B收到後也進入ESTABLISHED狀態。

抓包

在這裏插入圖片描述

第一次握手
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

爲什麼要三次握手

需要建立可靠的連接, 則雙方都需要確認雙方的接收請求和發送請求功能都正常。

  • 第一次握手,服務端B收到A的請求, 則B可以確認A的發送功能和B的接收功能都正常。
  • 第二次握手,客戶端A收到B的確認, 則A可以確認A和B的發送和接收功能都正常。
  • 第三次握手, 服務端B收到A的確認,則B可以確認A的接收功能和B的發送功能都正常。

因此, 三次握手才能夠建立可靠的連接。

只有兩次握手帶來的問題

  • 網絡中客戶端發送的滯留失效報文在延時的情況下到達服務端時, 服務器返回一次確認後便認爲連接已經建立, 而此時客戶端在CLOSE狀態並沒有發起連接, 則此時服務端進入無效的等待, 浪費資源.
  • 當服務器回答客戶端發送的滯留失效的延時報文時, 如果客戶端又恰好發起連接進入SYN-SENT狀態, 客戶端則會收到延時報文的確認, 從而會導致雙方得到了錯誤的的序號和確認號, 導致大量的數據包會被丟棄,造成系統資源的浪費。

TCP連接釋放

四次揮手

在這裏插入圖片描述

首先A和B都處於ESTABLISHED連接狀態

  1. A的應用進程先向其TCP發出連接釋放報文, 設置 FIN = 1 , seq = u, u爲前面傳送過的最後一個字節的序號加1, 並停止發送數據, 主動關閉連接, 進入FIN-WAIT-1狀態。
  2. B服務端收到連接釋放報文後發出確認, 確認序號ack = u + 1, seq = v 等於B之前傳送的報文的最後一個字節加1, 然後B進入CLOSE-WAIT狀態。此時連接處於半關閉狀態,A已經沒有數據要發送了, 但B若發送輸出A仍要接收。 這個狀態可能持續一段時間。A在收到B的確認後進入FIN-WAIT-2狀態,等待B的釋放連接報文。
  3. 若B已經沒有要向A發送的數據,其應用進程就通知TCP釋放連接。這時B發出連接釋放報文,設置FIN = 1 ,seq = w (表示半關閉狀態發送的最後一個字節序號加1), 重複上次的確認號ack = u + 1, 之後B進入LAST-ACK狀態, 等待A的確認。
  4. A在收到B的連接釋放報文段後,需對B進行回覆確認,在確認報文段中設置 ACK = 1, ack = w + 1, seq = u + 1(FIN = 1 消耗序列號), 之後進入TIME-WAIT狀態。 此時TCP連接還沒有被釋放掉, 必須經過2MSL後A才能進入CLOSE狀態。 MSL(Maxinmum Segment Lifetime)最長報文段壽命,RFC 793建議設置爲2分鐘,可根據具體情況對時長進行設置。所以進入TIME-WAIT後客戶端還要經過4分鐘才能進入CLOSE狀態。 服務端接接收到客戶端的確認報文後也進入CLOSE狀態。

抓包

在這裏插入圖片描述

TIME-WAIT

爲什麼客戶端A必須在TIME-WAIT狀態等待2MSL呢?

  • 第四次揮手, A發送最後一個ACK報文段有可能丟失, 處在LAST-ACK狀態的B收不到最後一個確認報文,導致B不能正常關閉連接進入CLOSE狀態。 而如果A等待2MSL,則B在收不到確認報文時會超時重傳第三次揮手的FIN + ACK報文, A在2MSL內可以繼續接受B發送的該報文,並重傳一次確認,重新啓動2MSL計時器。這樣就能夠保證B也能正常釋放TCP連接。
  • 2MSL可以使本連接持續時間內所產生的所有報文段都在網絡中消失。這樣可以使下一個新的連接不會出現舊的連接報文段。

保活計時器

如果客戶端與服務器建立了TCP連接後,客戶端突然發生了故障。使用保活計時器可以防止服務器繼續無效等待下去。

服務器每收到一次客戶的數據,就重新設置保活計時器,通常是兩小時。兩小時沒有收到客戶的數據,則服務器每隔75分鐘發送一個探測報文段。若連續發送10個仍無客戶響應,服務器就認爲客戶端出了故障,並關閉該鏈接。

TCP可靠傳輸

TCP通過超時重傳實現可靠傳輸。

當一個已經發送的報文在一定時間內未收到確認,則重傳該報文, 該時間成爲超時時間。

一個報文從發發送到收到確認所需的時間稱爲往返時間 RTT, 對RTT進行加權平均的往返時間成爲RTTs(平滑往返時間)。
在這裏插入圖片描述
其中,0 ≤ a < 1,RTTs 隨着 a 的增加更容易受到 RTT 的影響。

超時時間應該略大於RTTs值,TCP使用的超時時間:
123
其中 RTTd 爲偏差的加權平均值。

TCP滑動窗口

在這裏插入圖片描述

發送緩存用來存放:

  • 應用程序準傳送給TCP準備發送的數據
  • TCP已經發送但尚未收到確認的數據

接收緩存用來存放:

  • 按序到達的、但尚未被應用程序讀取的數據
  • 未按序到達的數據

滑動窗口是緩存的一部分, 用來暫時存放字節流。接收方通過TCP報文中的窗口字段告訴發送方自己的窗口大小,接收方通過該字段設置自己的發送窗口大小。

發送窗口裏的數據:

  • 已經發送但未確認的數據
  • 允許發送但還未來得及發送的數據

接收窗口裏的數據:

  • 未按序到達的數據
  • 可以被可以接收的數據

TCP爲全雙工通信,通信的雙方都有自己的發送窗口和接收窗口,也在同時發送和接收數據。

TCP流量控制

在這裏插入圖片描述

如圖, 如果發送方數據發送過快, 接收方的應用程序接收按序到達的數據太慢,就會導致接收緩存漸漸被填滿,造成數據的丟失。

利用滑動窗口機制可以方便地在TCP連接上實現對發送方的流量控制。

接收方發送的確認報文中的窗口字段可以用來控制發送方窗口大小,從而影響發送方的發送速率。

如果設置發送方的窗口爲0, 則發送方會啓動一個計時器, 定時發送探測報文, 從而防止產生僵局。

TCP擁塞控制

在計算機網絡中的帶寬, 交換節點的緩存和處理機等都是網絡的資源, 如果在某一時間對這些資源的需求超過了可提供的部分, 就會產生擁塞, 網絡性能就會變差, 。

因此當出現擁塞時, 發送方應當控制其傳送速率。

在這裏插入圖片描述

TCP 主要通過四個算法來進行擁塞控制:慢開始、擁塞避免、快重傳、快恢復。

在這裏插入圖片描述

慢開始與擁塞避免

發送方需要維護一個叫做擁塞窗口(cwnd)的狀態變量,注意擁塞窗口與發送方窗口的區別:擁塞窗口只是一個狀態變量,實際決定發送方能發送多少數據的是發送方窗口。

慢開始:令cwnd = 1, 發送方只能發送一個報文段, 在收到確認後,cwnd翻倍, cwnd = 2, 依次進行,cwnd的數量依次翻倍,2,4,8,16 …

擁塞避免: cwnd因爲成指數倍增長,增長速率非常快, 爲了避免增長過快導致的網絡擁塞, 需要設置一個慢開始門限 ssthresh, 當cwnd >= ssthresh時, 進入擁塞避免, 每個輪次只講cwnd增1。

如果出現了超時,則ssthresh 設置爲超時時的 cwnd / 2 , 再重新執行慢開始。

快重傳與快恢復

在這裏插入圖片描述

快重傳: 快重傳不需要接收方等待自己發送數據時稍待確認, 而是在接收數據後立即發送確認。 即使收到了失序的報文段也要立即發送正確的確認。

如圖, 接收方收到了M1, M2 的報文段後, M3報文段丟失,之後又收到了三個報文段M4,M5和M6, 併發送了三個M2的確認, 接收方收到三個隊M2的重複確認後立即重傳M3。

這種情況下, 只是出現意外丟失個別的報文段,而不是網絡擁塞, 因此執行快恢復,零ssthresh = cwnd / 2, cwnd = ssthresh, 並直接進入擁塞避免。

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