【計算機網絡】TCP 與 UDP

TCP 與 UDP

TCP/IP 協議是一個協議簇。裏面包括很多協議的,UDP 只是其中的一個。

TCP (Transmission Control Protocol)

TCP/IP 協議集包括應用層,傳輸層,網絡層,網絡訪問層。

TCP 是面向連接的單播協議。在收發數據前,必須和對方建立可靠的連接。它是面向連接的,提供可靠交付,有流量控制,擁塞控制,提供全雙工通信,支持半關閉連接,面向字節流(把應用層傳下來的報文看成字節流,把字節流組織成大小不等的數據塊),每一條 TCP 連接只能是點對點的(一對一)。

三次握手

img

一個 TCP 連接必須要經過三次“握手”才能建立起來。其過程爲:

  1. 第一次握手:主機 A 通過向主機 B 發送一個含有**同步序列號(SYN)**標誌位的數據段給主機 B,向主機 B 請求建立連接,seq = x 表示主機 A 自己的初始序號(第 x 號包)。通過這個數據段, 主機 A 告訴主機 B 兩件事:我想要和你通信;你可以用那個序列號作爲起始數據段來回應我。(SYN = 1,seq = x,主機 A 進入 syn_sent 狀態,該數據包不能攜帶數據)
  2. 第二次握手:主機 B 收到主機 A 的請求後,用一個帶有**確認應答(ACK)同步序列號(SYN)**標誌位的數據段響應主機 A,ACKnum 表示期望收到對方下一個報文段的第一個數據字節序號是 x+1,seq = y 表示主機 B 自己的初始序號(第 y 號包)。同時也告訴主機 A 兩件事:我已經收到你的請求了,你可以傳輸數據了;你要用那個序列號(x+1)作爲起始數據段來回應我。(SYN = 1,ACK = 1,ACKnum = x+1,seq = y,主機 B 進入 syn_rcvd 狀態
  3. 第三次握手:主機 A 收到這個數據段後,再發送一個確認應答(ACK),ACKnum 表示期望收到對方下一個報文段的第一個數據字節序號是 y+1,同時攜帶要發送給主機 B 的數據(通常爲一些配置信息,如滑動窗口的大小)。確認已收到主機 B 的數據段:"我已收到回覆,我現在要開始傳輸實際數據了“。(ACK = 1,ACKnum = y+1)一旦主機 B 收到確認後,這樣3次握手就完成了,這個 TCP 連接進入 Established 狀態,主機 A 和主機 B 就可以傳輸數據了。

經歷了上面的三次握手過程,客戶端和服務端都確認了自己的接收、發送能力是正常的。在進行最少次交互的情況下完成了兩端的資源分配初始化序號(客戶端 --> 服務器端: x。服務器端 --> 客戶端:y)的交換。

之所以不只是進行兩次握手,而有第三次握手,是爲了防止失效的連接請求到達服務器,讓服務器錯誤打開連接。採用三次握手,當服務器接收並且回覆確認了那條失效的連接請求,此時客戶端不會再次發出確認,由於服務器得不到確認,那麼就能知道客戶端並沒有請求該連接。

三次“握手”的目的是使數據包的發送和接收同步, 經過三次“握手”之後,主機 A 才向主機 B 正式發送數據。三次握手並不會涉及應用層的數據 , SYN 這個標誌位只有在 TCP 建立連接時纔會被置 1 ,握手完成後 SYN 標誌位被置 0。

四次揮手

img

  1. 當主機 A 完成數據傳輸後,將控制位 FIN 置1,提出停止 TCP 連接的請求 ;(FIN_WAIT_1)
  2. 主機 B 收到 FIN 後對其作出響應,確認這一方向上的 TCP 連接將關閉,將 ACK 置 1,避免引發不必要的 FIN 重傳;(FIN_WAIT_2 - CLOSE_WAIT)
  3. 由 B 端再提出反方向的關閉請求,將 FIN 置 1;(LAST_ACK)
  4. 主機 A 對主機 B 的請求進行確認,將 ACK 置 1,雙方向的關閉結束.。

TCP 連接是雙向傳輸的、對等的模式,就是說雙方都可以同時向對方發送或接收數據。當有一方要關閉連接時,會發送指令告知對方,我要關閉連接了。這時對方會回一個 ACK,此時一個方向的連接關閉。但是另一個方向仍然可以繼續傳輸數據,等到發送完了所有的數據後,會發送一個 FIN 段來關閉此方向上的連接。接收方發送 ACK 確認關閉連接。注意,接收到 FIN 報文的一方只能回覆一個 ACK , 它是無法馬上返回對方一個 FIN 報文段的,因爲結束數據傳輸的“指令”是上層應用層給出的,我只是一個“搬運工”,我無法瞭解“上層的意志”。

客戶端發送了 FIN 連接釋放報文之後,服務器收到了這個報文,就進入了 CLOSE-WAIT 狀態。這個狀態是爲了讓服務器端發送還未傳送完畢的數據,傳送完畢之後,服務器會發送 FIN 連接釋放報文。因爲服務端在 LISTEN 狀態下,收到建立連接請求的 SYN 報文後,把 ACK 和 SYN 放在一個報文裏發送給客戶端。而關閉連接時,當收到對方的 FIN 報文時,僅僅表示對方不再發送數據了但是還能接收數據,己方是否現在關閉發送數據通道,需要上層應用來決定,因此,己方 ACK 和 FIN 一般都會分開發。

TCP 的四次揮手有可能變成三次揮手。之所以斷開 tcp 連接需要四次揮手(2 + 2)是因爲 tcp 是全雙工通信且支持半關閉連接,即兩端向對方傳輸數據和終止在時序上是獨立的。

但如果服務器端收到客戶端的 FIN 包後,也沒數據要發送給客戶端了,那麼回覆給客戶端的 ACK 包和服務器自己的 FIN 包就可以合併成一個包發送過去。這樣四次揮手就編程三次了。

實際上有時候在抓包時會看到 FIN+ACK這樣的數據包,即三次揮手釋放 tcp 連接的數據包,這是因爲現在大多數實現都允許連接終止時使用三次揮手(但大部分情況下,還是以四次揮手爲主)。三次揮手適合在雙方都沒有數據要發送的情況下。

由 TCP 的三次握手和四次斷開可以看出,TCP 使用面向連接的通信方式,大大提高了數據通信的可靠性,使發送數據端和接收端在數據正式傳輸前就有了交互, 爲數據正式傳輸打下了可靠的基礎。

TCP 的短連接和長連接

**短連接:**Client 向 Server 發送消息,Server 迴應 Client,然後一次讀寫就完成了,這時候雙方任何一個都可以發起 close 操作,不過一般都是 Client 先發起 close 操作。短連接一般只會在 Client/Server 間傳遞一次讀寫操作。

短連接的優點:管理起來比較簡單,建立存在的連接都是有用的連接,不需要額外的控制手段。

**長連接:**Client 與 Server 完成一次讀寫之後,它們之間的連接並不會主動關閉,後續的讀寫操作會繼續使用這個連接。

在長連接的應用場景下,Client 端一般不會主動關閉它們之間的連接,Client 與 Server 之間的連接如果一直不關閉的話,隨着客戶端連接越來越多,Server 壓力也越來越大,這時候 Server 端需要採取一些策略,如關閉一些長時間沒有讀寫事件發生的連接,這樣可以避免一些惡意連接導致 Server 端服務受損;如果條件再允許可以以客戶端爲顆粒度,限制每個客戶端的最大長連接數,從而避免某個客戶端連累後端的服務。

長連接和短連接的產生在於 Client 和 Server 採取的關閉策略,具體的應用場景採用具體的策略

UDP (User Data Protocol)

UDP 是用戶數據報協議,它是無連接的,盡最大可能交付,沒有擁塞控制,面向報文(對於應用程序傳下來的報文不合並也不拆分,只是添加 UDP 首部),支持一對一、一對多、多對一和多對多的交互通信。

UDP 是一個非連接的協議,傳輸數據之前源端和終端不建立連接, 當它想傳送時就簡單地去抓取來自應用程序的數據,並儘可能快地把它扔到網絡上。 在發送端,UDP 傳送數據的速度僅僅是受應用程序生成數據的速度、 計算機的能力和傳輸帶寬的限制; 在接收端,UDP 把每個消息段放在隊列中,應用程序每次從隊列中讀一個消息段。

由於傳輸數據不建立連接,因此也就不需要維護連接狀態,包括收發狀態等, 因此一臺服務機可同時向多個客戶機傳輸相同的消息。UDP 信息包的標題很短,只有 8 個字節,相對於 TCP 的 20 個字節信息包的額外開銷很小。吞吐量不受擁擠控制算法的調節,只受應用軟件生成數據的速率、傳輸帶寬、 源端和終端主機性能的限制。

UDP 使用盡最大努力交付,即不保證可靠交付, 因此主機不需要維持複雜的鏈接狀態表(這裏面有許多參數)。UDP 是面向報文的。發送方的 UDP 對應用程序交下來的報文, 在添加首部後就向下交付給 IP 層。既不拆分,也不合並,而是保留這些報文的邊界, 因此,應用程序需要選擇合適的報文大小。

我們經常使用 ping 命令來測試兩臺主機之間 TCP/IP 通信是否正常, 其實 ping 命令的原理就是向對方主機發送UDP 數據包,然後對方主機確認收到數據包, 如果數據包是否到達的消息及時反饋回來,那麼網絡就是通的。

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