首部格式
圖釋:

各個段位說明:
- 源端口和目的端口:各占 2 位元組.端口是傳輸層與應用層的服務接口.傳輸層的複用和分用功能都要通過端口才能實作
- 序号:占 4 位元組.TCP 連接配接中傳送的資料流中的每一個位元組都編上一個序号.序号字段的值則指的是本封包段所發送的資料的第一個位元組的序号
- 确認号: 占 4 位元組,是期望收到對方的下一個封包段的資料的第一個位元組的序号
- 資料偏移/首部長度:占 4 位,它指出 TCP 封包段的資料起始處距離 TCP 封包段的起始處有多遠.“資料偏移”的機關是 32 位字(以 4 位元組為計算機關)
- 保留: 占 6 位,保留為今後使用,但目前應置為 0
- 标志位 占有6位,分别表示下面的标志
- 緊急URG:當 URG=1 時,表明緊急指針字段有效.它告訴系統此封包段中有緊急資料,應盡快傳送(相當于高優先級的資料)
- 确認ACK:隻有當 ACK=1 時确認号字段才有效.當 ACK=0 時,确認号無效
- PSH(PuSH): 接收 TCP 收到 PSH = 1 的封包段,就盡快地傳遞接收應用程序,而不再等到整個緩存都填滿了後再向上傳遞
- RST (ReSeT): 當 RST=1 時,表明 TCP 連接配接中出現嚴重差錯(如由于主機崩潰或其他原因),必須釋放連接配接,然後再重建立立運輸連接配接
- 同步 SYN: 同步 SYN = 1 表示這是一個連接配接請求或連接配接接受封包
- 終止 FIN: 用來釋放一個連接配接.FIN=1 表明此封包段的發送端的資料已發送完畢,并要求釋放運輸連接配接
- 檢驗和:占 2 位元組.檢驗和字段檢驗的範圍包括首部和資料這兩部分.在計算檢驗和時,要在 TCP 封包段的前面加上 12 位元組的僞首部
- 緊急指針:占 16 位,指出在本封包段中緊急資料共有多少個位元組(緊急資料放在本封包段資料的最前面)
- 選項:長度可變.TCP 最初隻規定了一種選項,即最大封包段長度 MSS.MSS 告訴對方 TCP:“我的緩存所能接收的封包段的資料字段的最大長度是 MSS 個位元組.” [MSS(Maximum Segment Size)是 TCP 封包段中的資料字段的最大長度.資料字段加上 TCP 首部才等于整個的 TCP 封包段]
- 視窗擴大: 占 3 位元組,其中有一個位元組表示移位值 S.新的視窗值等于TCP 首部中的視窗位數增大到(16 + S),相當于把視窗值向左移動 S 位後獲得實際的視窗大小
- 時間戳:占10 位元組,其中最主要的字段時間戳值字段(4位元組)和時間戳回送回答字段(4位元組)
- 選擇确認:接收方收到了和前面的位元組流不連續的兩2位元組.如果這些位元組的序号都在接收視窗之内,那麼接收方就先收下這些資料,但要把這些資訊準确地告訴發送方,使發送方不要再重複發送這些已收到的資料
- 填充 :這是為了使整個首部長度是 4 位元組的整數倍
資料機關
- TCP 傳送的資料機關協定是 TCP 封包段(segment)
特點
- TCP 是面向連接配接的傳輸層協定
- 每一條 TCP 連接配接隻能有兩個端點(endpoint),每一條 TCP 連接配接隻能是點對點的(一對一)
- TCP 提供可靠傳遞的服務
- TCP 提供全雙工通信
- 面向位元組流
注意
- TCP 對應用程序一次把多長的封包發送到TCP 的緩存中是不關心的
- TCP 根據對方給出的視窗值和目前網絡擁塞的程度來決定一個封包段應包含多少個位元組(UDP 發送的封包長度是應用程序給出的)
-
TCP 可把太長的資料塊劃分短一些再傳送.TCP 也可等待積累有足夠多的位元組後再構成封包段發送出去
每一條 TCP 連接配接有兩個端點
- TCP 連接配接的端點不是主機,不是主機的IP 位址,不是應用程序,也不是傳輸層的協定端口.TCP 連接配接的端點叫做套接字(socket)或插口
自動重傳請求ARQ
定義:
可靠傳輸協定常稱為自動重傳請求ARQ (Automatic Repeat reQuest)
累積确認:
- 定義: 接收方一般采用累積确認的方式.即不必對收到的分組逐個發送确認,而是對按序到達的最後一個分組發送确認,這樣就表示:到這個分組為止的所有分組都已正确收到了
- 優點: 容易實作,即使确認丢失也不必重傳
- 缺點: 不能向發送方反映出接收方已經正确收到的所有分組的資訊
Go-back-N(回退N):
如果發送方發送了前 5 個分組,而中間的第 3 個分組丢失了.這時接收方隻能對前兩個分組發出确認.發送方無法知道後面三個分組的下落,而隻好把後面的三個分組都再重傳一次
具體實作
說明:
- TCP 連接配接的每一端都必須設有兩個視窗 一個發送視窗和一個接收視窗
- TCP 可靠傳輸機制用位元組的序号進行控制.TCP 所有的确認都是基于序号而不是基于封包段
- TCP 兩端的四個視窗經常處于動态變化之中
- TCP 連接配接的往返時間 RTT 也不是固定不變的.需要使用特定的算法估算較為合理的重傳時間
圖釋:
發送緩存
發送緩存用來暫時存放:
- 發送應用程式傳送給發送方 TCP 準備發送的資料
- TCP 已發送出但尚未收到确認的資料
接收緩存
接收緩存用來暫時存放:
- 按序到達的、但尚未被接收應用程式讀取的資料;
- 不按序到達的資料
滑動視窗
特點:
- 以位元組為機關的滑動視窗
- A 的發送視窗并不總是和 B 的接收視窗一樣大(因為有一定的時間滞後)
要求:
- TCP 标準沒有規定對不按序到達的資料應如何處理.通常是先臨時存放在接收視窗中,等到位元組流中所缺少的位元組收到後,再按序傳遞上層的應用程序
- TCP 要求接收方必須有累積确認的功能,這樣可以減小傳輸開銷
具體實作:
确認丢失和确認遲到
逾時重傳時間選擇
RTT,RTO
- RTT(Round Trip Time):一個連接配接的往返時間,即資料發送時刻到接收到确認的時刻的內插補點;
- RTO(Retransmission Time Out):重傳逾時時間,即從資料發送時刻算起,超過這個時間便執行重傳。
- RTT和RTO 的關系是:由于網絡波動的不确定性,每個RTT都是動态變化的,是以RTO也應随着RTT動态變化。
TCP 每發送一個封包段,就對這個封包段設定一次計時器.隻要計時器設定的重傳時間到但還沒有收到确認,就要重傳這一封包段
權重平均往返時間:
做法:
TCP 保留了 RTT 的一個權重平均往返時間 RTTS(這又稱為平滑的往返時間),第一次測量到 RTT 樣本時,RTTS 值就取為所測量到的 RTT 樣本值.以後每測量到一個新的 RTT 樣本,就按下式重新計算一次 RTTS:
公式:
新的 RTTS = ( 1 - α)×(舊的 RTTS)+α(新的 RTT 樣本)
式中,0 ≤ α< 1.若α很接近于零,表示 RTT 值更新較慢若選擇 α 接近于1,則表示 RTT 值更新較快
RFC 2988 推薦的 α 值為 1/8,即 0.125
逾時重傳時間RTO:
RTO 應略大于上面得出的權重平均往返時間 RTTS.
RFC 2988 建議使用下式計算 RTO:
RTO=RTTS + 4×RTTD
RTTD 是 RTT 的偏差的權重平均值
RFC 2988 建議這樣計算 RTTD.第一次測量時,RTTD 值取為測量到的 RTT 樣本值的一半.在以後的測量中,則使用下式計算權重平均的 RTTD:
新的 RTTD = (1-β)×(舊的RTTD)+β×|RTTS﹣新的 RTT 樣本|
β是個小于 1 的系數,其推薦值是 1/4,即 0.25
在計算平均往返時間 RTT 時,隻要封包段重傳了,就不采用其往返時間樣本
修正的Karn算法:
封包段每重傳一次,就把 RTO 增大一些:
新的 RTO= γ×(舊的 RTO)
系數γ 的典型值是 2
當不再發生封包段的重傳時,才根據封包段的往返時延更新平均往返時延 RTT 和逾時重傳時間 RTO 的數值
持續計時器
- TCP 為每一個連接配接設有一個持續計時器
- 隻要 TCP 連接配接的一方收到對方的零視窗通知,就啟動持續計時器
- 若持續計時器設定的時間到期,就發送一個零視窗探測封包段(僅攜帶 1 位元組的資料),而對方就在确認這個探測封包段時給出了現在的視窗值
- 若視窗仍然是零,則收到這個封包段的一方就重新設定持續計時器
- 若視窗不是零,則死鎖的僵局就可以打破了
封包段的發送時機
TCP 維持一個變量,它等于最大封包段長度 MSS.隻要緩存中存放的資料達到 MSS 位元組時,就組裝成一個 TCP 封包段發送出去
由發送方的應用程序指明要求發送封包段,即 TCP 支援的推送(push)操作
發送方的一個計時器期限到了,這時就把目前已有的緩存資料裝入封包段(但長度不能超過 MSS)發送出去
運輸連接配接
三個階段:
- 連接配接建立:
-
- 步驟:
- A 的 TCP 向 B 發出連接配接請求封包段,其首部中的同步位 SYN = 1,并選擇序号 seq = x,表明傳送資料時的第一個資料位元組的序号是 x
- B 的 TCP 收到連接配接請求封包段後,如同意,則發回确認(B 在确認封包段中應使 SYN = 1,使 ACK = 1,其确認号ack = x﹢1,自己選擇的序号 seq = y)
- A 收到此封包段後向 B 給出确認,其 ACK = 1,确認号 ack = y﹢1(A 的 TCP 通知上層應用程序,連接配接已經建立,B 的 TCP 收到主機 A 的确認後,也通知其上層應用程序:TCP 連接配接已經建立)
- 步驟:
- 資料傳送
- 連接配接釋放:
-
-
- 資料傳輸結束後,通信的雙方都可釋放連接配接.現在 A 的應用程序先向其 TCP 發出連接配接釋放封包段,并停止再發送資料,主動關閉 TCP 連接配接(A 把連接配接釋放封包段首部的 FIN = 1,其序号seq = u,等待 B 的确認)
- B 發出确認,确認号 ack = u+1,而這個封包段自己的序号 seq = v(TCP 伺服器程序通知高層應用程序.從 A 到 B 這個方向的連接配接就釋放了,TCP 連接配接處于半關閉狀态.B 若發送資料,A 仍要接收)
- 若 B 已經沒有要向 A 發送的資料,其應用程序就通知 TCP 釋放連接配接
- A 收到連接配接釋放封包段後,必須發出确認,在确認封包段中 ACK = 1,确認号 ack=w﹢1,自己的序号 seq = u + 1
-
注意:
TCP 連接配接必須經過時間 2MSL 後才真正釋放掉(2MSL 的時間的用意 --- 為了保證 A 發送的最後一個 ACK 封包段能夠到達 B.防止 “已失效的連接配接請求封包段”出現在本連接配接中.A 在發送完最後一個 ACK 封包段後,再經過時間 2MSL,就可以使本連接配接持續的時間内所産生的所有封包段,都從網絡中消失.這樣就可以使下一個新的連接配接中不會出現這種舊的連接配接請求封包段)
-
-
- 發現丢失确認時候的處理:
三個問題:
- 要使每一方能夠确知對方的存在
- 要允許雙方協商一些參數(如最大封包段長度,最大視窗大小,服務品質等)
- 能夠對運輸實體資源(如緩存大小,連接配接表中的項目等)進行配置設定
發送TCP請求用戶端
擁塞處理相關概念
擁塞視窗:
含義:
擁塞視窗的大小取決于網絡的擁塞程度,并且動态地在變化.發送方讓自己的發送視窗等于擁塞視窗.如再考慮到接收方的接收能力,則發送視窗還可能小于擁塞視窗
發送方控制擁塞視窗的原則:
隻要網絡沒有出現擁塞,擁塞視窗就再增大一些,以便把更多的分組發送出去.但隻要網絡出現擁塞,擁塞視窗就減小一些,以減少注入到網絡中的分組數
乘法減小:
是指不論在慢開始階段還是擁塞避免階段,隻要出現一次逾時(即出現一次網絡擁塞),就把慢開始門限值 ssthresh 設定為目前的擁塞視窗值乘以 0.5
加法增大:
是指執行擁塞避免算法後,在收到對所有封包段的确認後(即經過一個往返時間),就把擁塞視窗 cwnd增加一個 MSS 大小,使擁塞視窗緩慢增大,以防止網絡過早出現擁塞
快重傳:
快重傳算法首先要求接收方每收到一個失序的封包段後就立即發出重複确認.這樣做可以讓發送方及早知道有封包段沒有到達接收方,發送方隻要一連收到三個重複确認就應當立即重傳對方尚未收到的封包段
快恢複:
當發送端收到連續三個重複的确認時,就執行“乘法減小”算法,把慢開始門限 ssthresh 減半.但接下去不執行慢開始算法
發送視窗的上限值:
發送方的發送視窗的上限值應當取為接收方視窗 rwnd 和擁塞視窗 cwnd 這兩個變量中較小的一個,即應按以下公式确定:
發送視窗的上限值 Min [rwnd, cwnd]
-
- 當 rwnd < cwnd 時,是接收方的接收能力限制發送視窗的最大值
- 當 cwnd < rwnd 時,則是網絡的擁塞限制發送視窗的最大值
免擁塞具體實作
慢開始算法:
- 在主機剛剛開始發送封包段時可先設定擁塞視窗 cwnd = 1,即設定為一個最大封包段 MSS 的數值
- 在每收到一個對新的封包段的确認後,将擁塞視窗加 1,即增加一個 MSS 的數值
- 使用慢開始算法後,每經過一個傳輸輪次(往返時間 RTT),擁塞視窗 cwnd 就加倍
擁塞避免算法:
擁塞視窗 cwnd 緩慢地增大,即每經過一個往返時間 RTT 就把發送方的擁塞視窗 cwnd 加 1,使擁塞視窗 cwnd 按線性規律緩慢增長
慢開始門限 ssthresh 的用法:
- 當 cwnd < ssthresh 時,使用慢開始算法
- 當 cwnd > ssthresh 時,停止使用慢開始算法而改用擁塞避免算法
- 當 cwnd = ssthresh 時,既可使用慢開始算法,也可使用擁塞避免算法
網絡出現擁塞時(其根據就是沒有按時收到确認):
- 就要把慢開始門限 ssthresh 設定為出現擁塞時的發送方視窗值的一半(但不能小于2)
- 然後把擁塞視窗 cwnd 重新設定為 1.執行慢開始算法
TCP 的有限狀态機
- TCP 有限狀态機的圖中每一個方框都是 TCP 可能具有的狀态
- 每個方框中的大寫英文字元串是 TCP 标準所使用的 TCP 連接配接狀态名.狀态之間的箭頭表示可能發生的狀态變遷
- 箭頭旁邊的字,表明引起這種變遷的原因,或表明發生狀态變遷後又出現什麼動作
- 圖中有三種不同的箭頭
- 粗實線箭頭表示對客戶程序的正常變遷
- 粗虛線箭頭表示對伺服器程序的正常變遷
- 另一種細線箭頭表示異常變遷