1. 程式人生 > >(3)傳輸層UDP和TCP協議

(3)傳輸層UDP和TCP協議

傳輸層UDP和TCP協議

簡介

兩個主機進行通訊實際上就是兩個主機中的應用程序互相通訊。 應用程序之間的通訊又稱為端到端的通訊。

網路層是為主機之間提供邏輯通訊,而傳輸層為應用程序之間提供端到端的邏輯通訊。傳輸層還要對收到的報文進行差錯檢測。

傳輸層需要有兩種不同的傳輸協議,即面向連線的 傳輸控制協議TCP(Transmission Control Protocol) 和無連線的 使用者資料報協議UDP(User Datagram Protocol)。

  • 當傳輸層採用面向連線的 TCP 協議時,儘管下面的網路是不可靠的(只提供盡最大努力服務),但這種邏輯通訊通道就相當於一條全雙工的可靠通道。

  • 當傳輸層採用無連線的 UDP 協議時,這種邏輯通訊通道是一條不可靠通道。

兩個對等傳輸實體在通訊時傳送的資料單位叫作傳輸協議資料單元 TPDU (Transport Protocol Data Unit)。

  • TCP 傳送的資料單位協議是 TCP 報文段(segment)

  • UDP 傳送的資料單位協議是 UDP 報文或使用者資料報。

選擇哪種協議?

  • UDP 在傳送資料之前不需要先建立連線。對方的傳輸層在收到 UDP 報文後,不需要給出任何確認。雖然 UDP 不提供可靠交付,但在某些情況下 UDP 是一種最有效的工作方式。

  • TCP 則提供面向連線的服務。TCP 不提供廣播或多播服務。由於 TCP 要提供可靠的、面向連線的傳輸服務,因此不可避免地增加了許多的開銷。這不僅使協議資料單元的首部增大很多,還要佔用許多的處理機資源。

使用者資料報協議UDP(User Datagram Protocol)

UDP 只在 IP 的資料報服務之上增加了埠的功能和差錯檢測的功能。

UDP 的主要特點:

  • UDP 是無連線的,即傳送資料之前不需要建立連線。

  • UDP 使用盡最大努力交付,即不保證可靠交付,同時也不使用擁塞控制。

  • UDP 是面向報文的。UDP 沒有擁塞控制,很適合多媒體通訊的要求。

  • UDP 支援一對一、一對多、多對一和多對多的互動通訊。

  • UDP 的首部開銷小,只有 8 個位元組。

面向報文的 UDP

面向報文的UDP

  • 傳送方 UDP 對應用程式交下來的報文,在新增首部後就向下交付 IP 層。UDP 對應用層交下來的報文,既不合並,也不拆分,而是保留這些報文的邊界。

  • 應用層交給 UDP 多長的報文,UDP 就照樣傳送,即一次傳送一個報文。

  • 接收方 UDP 對 IP 層交上來的 UDP 使用者資料報,在去除首部後就原封不動地交付上層的應用程序,一次交付一個完整的報文。

  • 應用程式必須選擇合適大小的報文。

UDP首部格式

UDP首部格式

使用者資料報 UDP 有兩個欄位:資料欄位和首部欄位。首部欄位有 8 個位元組,由 4 個欄位組成,每個欄位都是兩個位元組。

  • UDP埠號

    由於很多軟體需要用到UDP協議,所以UDP協議必須通過某個標誌用以區分不同的程式所需要的資料包。埠號的功能就在於此,例如某一個UDP程式A在系統中註冊了3000埠,那麼,以後從外面傳進來的目的埠號為3000的UDP包都會交給該程式。埠號理論上可以有216這麼多。因為它的長度是16個bit。

  • UDP檢驗和

    UDP檢驗和 覆蓋UDP協議頭和資料,這和IP的檢驗和是不同的,IP協議的檢驗和只是覆蓋IP資料頭,並不覆蓋所有的資料。UDP和TCP都包含一個偽首部,這是為了計算檢驗和而設定的。偽首部甚至還包含IP地址這樣的IP協議裡面都有的資訊,目的是讓UDP兩次檢查資料是否已經正確到達目的地。如果傳送端沒有開啟檢驗和選項,而接收端計算檢驗和有差錯,那麼UDP資料將會被悄悄的丟掉(不保證送達),而不產生任何差錯報文。

傳輸控制協議TCP(Transmission Control Protocol)

TCP是一種面向連線的、可靠的基於位元組流的傳輸層通訊協議。TCP將使用者資料打包成報文段,它傳送後啟動一個定時器,另一端對收到的資料進行確認、對失序的資料重新排序、丟棄重複資料。

TCP 最主要的特點:

  • TCP 是面向連線的傳輸層協議。

  • 每一條 TCP 連線只能有兩個端點(endpoint),每一條 TCP 連線只能是點對點的(一對一)。

  • TCP 提供可靠交付的服務。

  • TCP 提供全雙工(full-duplex)通訊。這個全雙工的通訊將佔用兩個計算機之間的通訊線路,直到它被一方或雙方關閉為止。

  • 面向位元組流。 面向位元組流的含義:雖然應用程式和TCP互動是一次一個資料塊,但TCP把應用程式交下來的資料僅僅是一連串的無結構的位元組流。

TCP套接字

每一條 TCP 連線有兩個端點。TCP 連線的端點叫做套接字(socket)或插口。

埠號拼接到(contatenated with) IP 地址即構成了套接字。

套接字 socket = (IP地址: 埠號)

每一條 TCP 連線唯一地被通訊兩端的兩個端點(即兩個套接字)所確定。即:

TCP 連線 ::= {socket1, socket2} 
           = {(IP1: port1), (IP2: port2)}   

TCP連線建立階段對套接字的操作:

  1. 當套接字被建立後,它的埠號和 IP 地址都是空的,因此應用程序要呼叫 bind(繫結)來指明套接字的本地地址。在伺服器端呼叫 bind 時就是把熟知埠號和本地IP地址填寫到已建立的套接字中。這就叫做把本地地址繫結到套接字。

  2. 伺服器在呼叫 bind 後,還必須呼叫 listen(收聽)把套接字設定為被動方式,以便隨時接受客戶的服務請求。UDP伺服器由於只提供無連線服務,不使用 listen 系統呼叫。

  3. 伺服器緊接著就呼叫 accept(接受),以便把遠地客戶程序發來的連線請求提取出來。系統呼叫 accept 的一個變數就是要指明從哪一個套接字發起的連線。

TCP面向流的概念

TCP面向流的概念

注意:

  • TCP 對應用程序一次把多長的報文傳送到TCP 的快取中是不關心的。

  • TCP 根據對方給出的視窗值和當前網路擁塞的程度來決定一個報文段應包含多少個位元組(UDP 傳送的報文長度是應用程序給出的)。

  • TCP 可把太長的資料塊劃分短一些再傳送。TCP 也可等待積累有足夠多的位元組後再構成報文段傳送出去。

TCP報文首部格式

TCP報文首部格式

  • 序號——TCP 連線中傳送的資料流中的每一個位元組都編上一個序號。序號欄位的值指的是本報文段所傳送的資料的第一個位元組的序號。

  • 確認號欄位——期望收到對方的下一個報文段的資料的第一個位元組的序號。

  • 資料偏移(即首部長度)——指出 TCP 報文段的資料起始處距離 TCP 報文段的起始處有多遠。“資料偏移”的單位是 32 位字(以 4 位元組為計算單位)。

  • 緊急 URG —— 當 URG =1 時,表明緊急指標欄位有效。它告訴系統此報文段中有緊急資料,應儘快傳送(相當於高優先順序的資料)。

  • 確認 ACK —— 只有當 ACK= 1 時確認號欄位才有效。當 ACK = 0 時,確認號無效。

  • 推送 PSH (PuSH) —— 接收 TCP 收到 PSH = 1 的報文段,就儘快地交付接收應用程序,而不再等到整個快取都填滿了後再向上交付。

  • 復位 RST (ReSeT) —— 當 RST = 1 時,表明 TCP 連線中出現嚴重差錯(如由於主機崩潰或其他原因),必須釋放連線,然後再重新建立傳輸連線。

  • 同步 SYN —— 同步 SYN = 1 表示這是一個連線請求或連線接收報文。

  • 終止 FIN (FINis) —— 用來釋放一個連線。FIN = 1 表明此報文段的傳送端的資料已傳送完畢,並要求釋放傳輸連線。

  • 視窗欄位 —— 用來讓對方設定傳送視窗的依據,單位為位元組。

  • 檢驗和 —— 檢驗和欄位檢驗的範圍包括首部和資料這兩部分。在計算檢驗和時,要在 TCP 報文段的前面加上 12 位元組的偽首部。

  • 緊急指標欄位 —— 指出在本報文段中緊急資料共有多少個位元組(緊急資料放在本報文段資料的最前面)。

  • 選項欄位 —— 長度可變。

    • 最大報文段長度 MSS(Maximum Segment Size)。MSS 告訴對方 TCP:“我的快取所能接收的報文段的資料欄位的最大長度是 MSS 個位元組。” MSS
      是 TCP 報文段中的資料欄位的最大長度。資料欄位加上 TCP 首部才等於整個的 TCP 報文段。

    • 視窗擴大選項 ——佔 3 位元組,其中有一個位元組表示移位值 S。新的視窗值等於TCP 首部中的視窗位數增大到(16 + S),相當於把視窗值向左移動 S 位後獲得實際的視窗大小。

    • 時間戳選項——佔10 位元組,其中最主要的欄位時間戳值欄位(4 位元組)和時間戳回送回答欄位(4 位元組)。

    • 選擇確認選項——告知傳送方不要再重複傳送已收到的資料。

  • 填充欄位 —— 這是為了使整個首部長度是 4 位元組的整數倍。

TCP可靠傳輸

TCP可靠傳輸包含以下內容:

  1. 校驗和、超時、確認機制
  2. 以位元組流為單位的滑動視窗
  3. 利用滑動視窗進行流量控制
  4. 擁塞控制,利用慢開始和避免擁塞演算法,快重傳和快恢復演算法
  5. 利用三次握手進行TCP連線
  6. 利用四次揮手釋放TCP 連線

TCP可靠傳輸的工作原理簡述如下:

  1. 應用資料被分割成TCP認為最適合傳送的資料塊。

  2. 當TCP發出一個段後,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。

  3. 當TCP收到發自TCP連線另一端的資料,它將傳送一個確認。這個確認不是立即傳送,通常將推遲幾分之一秒。

  4. TCP將保持它首部和資料的檢驗和。這是一個端到端的檢驗和,目的是檢測資料在傳輸過程中的任何變化。如果收到段的檢驗和有差錯, TCP將丟棄這個報文段和不確認收到此報文段(希望發端超時並重發)。

  5. 既然TCP報文段作為IP資料報來傳輸,而IP資料報的到達可能會失序,因此TCP報文段的到達也可能會失序。如果必要,TCP將對收到的資料進行重新排序,將收到的資料以正確的順序交給應用層。

  6. TCP還能提供流量控制。TCP連線的每一方都有固定大小的緩衝空間。TCP的接收端只允許另一端傳送接收端緩衝區所能接納的資料。這將防止較快主機致使較慢主機的緩衝區溢位。

確認和重傳機制

停止等待協議

確認丟失和確認遲到

注意:

  • 在傳送完一個分組後,必須暫時保留已傳送的分組的副本。
  • 分組和確認分組都必須進行編號。
  • 超時計時器的重傳時間應當比資料在分組傳輸的平均往返時間更長一些。

使用上述的確認和重傳機制,我們就可以在不可靠的傳輸網路上實現可靠的通訊。

這種可靠傳輸協議常稱為自動重傳請求ARQ (Automatic Repeat reQuest)。ARQ 表明重傳的請求是自動進行的。接收方不需要請求傳送方重傳某個出錯的分組 。

滑動視窗

  • TCP 連線的每一端都必須設有兩個視窗——一個傳送視窗和一個接收視窗。

  • TCP 的可靠傳輸機制用位元組的序號進行控制。TCP 所有的確認都是基於序號而不是基於報文段。

  • TCP 兩端的四個視窗經常處於動態變化之中。

  • TCP連線的往返時間 RTT 也不是固定不變的。需要使用特定的演算法估算較為合理的重傳時間。

持續計時器 (persistence timer)

TCP 為每一個連線設有一個持續計時器。

只要 TCP 連線的一方收到對方的零視窗通知,就啟動持續計時器。

若持續計時器設定的時間到期,就傳送一個零視窗探測報文段(僅攜帶 1 位元組的資料),而對方就在確認這個探測報文段時給出了現在的視窗值。

若視窗仍然是零,則收到這個報文段的一方就重新設定持續計時器。

若視窗不是零,則死鎖的僵局就可以打破了。

TCP連線的建立和中止

TCP是一個面向連線的協議,所以在連線雙方傳送資料之前,都需要首先建立一條連線。

一個TCP資料的傳送經歷如下過程:

  1. 雙方建立連線。

  2. 傳送方給接收方TCP資料報,然後等待對方的確認TCP資料報,如果沒有,就重新發,如果有,就傳送下一個資料報。

  3. 接收方等待發送方的資料報,如果得到資料報並檢驗無誤,就傳送ACK(確認)資料報,並等待下一個TCP資料報的到來。直到接收到FIN(傳送完成資料報)。

  4. 中止連線。

TCP三次握手建立連線

TCP三次握手

  1. 第一次握手:A 的 TCP 向 B 發出連線請求報文段,其首部中的同步位 SYN = 1,並選擇序號 seq = x,表明傳送資料時的第一個資料位元組的序號是 x。

  2. 第二次握手:B 的 TCP 收到連線請求報文段後,如同意,則發回確認。B 在確認報文段中應使 SYN = 1,使 ACK = 1,其確認號ack = x + 1,自己選擇的序號 seq = y。

  3. 第三次握手:A 收到此報文段後向 B 給出確認,其 ACK = 1,確認號 ack = y + 1。A 的 TCP 通知上層應用程序,連線已經建立。B 的 TCP 收到主機 A 的確認後,也通知其上層應用程序,TCP 連線已經建立。

在建立連線的時候,通訊的雙方要互相確認最大報文長度(Maximum Segement Size,MSS),以便通訊。

為什麼需要三次握手?

對於建立連線的三次握手,主要是要初始化Sequence Number的初始值。通訊的雙方要互相通知對方自己的初始化Sequence Number值,所以這個過程也叫SYN同步。也就是上圖中的x和y,這個序號要作為以後通訊使用的序號,以保證應用層接收到的資料不會因為網路上的傳輸問題而亂序(TCP會使用這個序號來拼接資料)。

TCP四次揮手釋放連線

TCP四次握手

  1. 第一次揮手:資料傳輸結束後,通訊的雙方都可釋放連線。現在 A 的應用程序先向其 TCP 發出連線釋放報文段,並停止再發送資料,主動關閉 TCP 連線。A 把連線釋放報文段首部的 FIN = 1,其序號seq = u,等待 B 的確認。

  2. 第二次揮手:B 發出確認,確認號 ack = u + 1,而這個報文段自己的序號 seq = v。TCP 伺服器程序通知高層應用程序。從 A 到 B 這個方向的連線就釋放了,TCP 連線處於半關閉(TCP提供了連線的一端在結束它的傳送後還能接收來自另一端資料的能力)狀態。B 若傳送資料,A 仍要接收。

  3. 第三次揮手:若 B 已經沒有要向 A 傳送的資料,其應用程序就通知 TCP 釋放連線。

  4. 第四次揮手:A 收到連線釋放報文段後,必須發出確認。在確認報文段中 ACK = 1,確認號 ack = w+ 1,自己的序號 seq = u + 1。TCP 連線必須經過時間 2MSL 後才真正釋放掉。

為什麼A 必須等待 2MSL 的時間?

  1. 為了保證 A 傳送的最後一個 ACK 報文段能夠到達 B。

  2. 防止 “已失效的連線請求報文段”出現在本連線中。A 在傳送完最後一個 ACK 報文段後,再經過時間 2MSL,就可以使本連線持續的時間內所產生的所有報文段,都從網路中消失。這樣就可以使下一個新的連線中不會出現這種舊的連線請求報文段。