1. 前言
TCP 和 UDP 協議是計算機網絡的重要組成協議,兩者經常被拿來比較,其中 TCP 協議往往會被面試官深入考察。
本節課程將和大家一起學習傳輸層的 TCP 和 UDP 協議。通過本節課程,你會了解到 TCP 和 UDP 協議的區別,重點是要掌握 TCP 協議的三次握手過程以及三次握手的必要性。
2.1 TCP 和 UDP
面試官提問: TCP 協議和 UDP 協議有什么區別?有什么共同點?
題目解析:
相同點:兩個協議最大的共同點是都位于 TCP/IP 網絡模型的傳輸層。
不同點:我們通過表格的形式對比不同。
TCP(Transmission Control Protocol,傳輸控制協議) | UDP(User Datagram Protocol,用戶數據報協議) | |
---|---|---|
是否連接 | 面向連接 | 無連接 |
傳輸方式 | 面向字節流:直接以字節流形式傳輸 | 面向報文:對于應用程序交付的數據,添加首部之后就交付給 IP 層 |
首部格式 | 20 個字節的固定首部 | 只有 8 個字節 |
是否可靠 | 可靠傳輸,依靠流量控制和擁塞控制 | 不可靠傳輸 |
連接對象個數 | 一對一連接 | 支持一對一(點到點),一對多以及多對多傳輸 |
適用場景 | 要求可靠傳輸的場景,例如發送郵件和傳輸文件 | 對可靠性要求低,效率要求高的場景,例如 QQ 的視頻通話 |
根據表格中的特點對比我們可以總結得到:
- TCP 協議面向連接并且可靠,UDP 協議無連接并且不可靠;
- 雖然 UDP 協議不可靠,但是在對數據完整性要求低,對傳輸速度要求高的場景,可以適用 UDP 協議。
2.2 TCP 和 UDP 報文
面試官提問: 上述你提到了 UDP 和 TCP 報文,它們的具體結構是怎樣的?
題目解析:
在上個題目中我們總結了 TCP 協議和 UDP 協議的不同點,其中談到了 TCP 和 UDP 協議首部格式不同,接下來分別畫圖分析。
?
如上圖可見,UDP 首部只有 8 個字節的數據,包括源端口號、目標端口號、長度以及校驗和。
- 源端口號:發送計算機的應用端口;
- 目標端口號:接收端計算機的接收端口,也是占用 16 位 Bit;
- 長度:表示 UDP 報文首部以及攜帶數據的長度;
- 校驗和:校驗數據在傳輸過程中是否損壞。
?
在畫完了示意圖之后,關于 TCP 報文首部,我們需要解釋的字段:
-
序號:對字節流編號,例如本次傳輸的序號是 100,攜帶的數據長度是 100 字節,那么下次傳輸的序號就是 200;
-
確認號:客戶端 A 往服務器端 B 發送了一個報文,序號是 100,攜帶的數據長度是 100 字節,那么 B 往 A 發送的報文中確認號就是 200,表示期望收到的下一個報文的序號。
-
標志位 CWR(Congestion Window Reduce):擁塞窗口減少標志;
-
標志位 ECE(ECN Echo):ECE 標志等于 1 時,通知接收方,表示接收方到這邊的網絡存在擁塞;
-
標志位 URG(Urgent):本報文是否包含緊急數據,只有當 URG=1 時,"校驗和" 后面的 "緊急指針" 字段才有效;
-
標志位 ACK(Acknowledgement):ACK=1 則表示前面發送的確認號是否有效,TCP 連接建立之后,ACK 必須設置為 1;
-
標志位 PSH(Push):PSH 設置為 1 則表示需要將收到的數據立即傳輸給上層應用,否則先放緩存;
-
標志位 RST(Reset):RST 設置為 1 則表示 TCP 連接出現異常,需要強制斷開;
-
標志位 SYN(Synchronize):SYN 設置為 1 則表示希望建立連接;
-
標志位 FIN(Finsish):FIN 設置為 1 則表示數據已經發送完成,可以斷開 TCP 連接。
上述定義中,序號、確認號以及 ACK、SYN 和 FIN 標志位是我們需要重點關注的部分,因為在 TCP 建立連接和斷開連接時會涉及到。
2.3 TCP 三次握手
面試官提問: TCP 是如何建立連接的?分析下每個步驟傳輸了什么樣的數據?
題目解析:
?
首先從行為上分析,TCP 建立連接需要發送三次報文,也就是 "三次握手" 的過程。
我們定義發送報文的一方是客戶端,接收報文的一方是服務器端。
首先服務器端處于監聽(LISTEN)的狀態,否則不會收到客戶端發來的請求。
(1)第一次握手:客戶端往服務器端發送一個請求建立連接報文,報文首部 SYN 標志位 = 1,給定一個初始的 Seq 序號 x。之后客戶端進入 SYN_SEN(同步發送)狀態;
(2)第二次握手:服務器端收到請求報文,如果同意建立連接,則向客戶端發送確認報文。確認報文中 SYN 標志位 = 1,ACK 標志位 = 1,同時給定一個 Seq 序號 y,Ack 確認號 x+1,之后服務器端進入 SYN_RCVD(同步已發送)狀態;
(3)第三次握手:客戶端收到來自服務器端的確認報文之后,還需要向服務器端發送確認報文,報文首部 ACK 標志位 = 1,Ack 確認號為 y+1,發送之后客戶端進入 ESTABLISHED(已建立連接)的狀態。服務器端收到確認報文后,也會進入 ESTABLISHED 狀態,在此之后,客戶端和服務器端可以開始 TCP 通信了。
2.4 TCP 三次握手的必要性
2.4.1 三次握手的意義
面試官提問: TCP 建立連接為什么需要三次握手?可以只有兩次握手嗎?第三次握手有什么意義?
題目解析:
緊接上面一個問題,如果我們能夠成功畫出 TCP 三次握手的過程,以及分析每個過程傳輸報文的首部內容,那么面試官大概率會拋出這樣一個問題,考察我們對 TCP 三次握手的理解。
首先從定性角度來看,分析三次握手每個步驟的意義:
(1)第一次握手:客戶端發送報文,服務器端接收報文,如果成功接收,說明客戶端的發送能力、服務器端的接收能力符合預期;
(2)第二次握手:服務器端發送報文,客戶端接收報文,如果成功接收。從客戶端的角度來看:客戶端的發送和接收能力符合預期,服務器端的發送和接收能力符合預期,可以建立連接。但是從服務器端的角度來看:客戶端的發送能力符合預期(第一次握手),服務器端的接收能力符合預期(第二次握手),但是因為收不到客戶端的反饋(無法獲知第二次握手的報文是否成功抵達客戶端),那么只能得出服務器端的發送能力和客戶端的接收能力不一定符合預期的結論;
(3)第三次握手:客戶端發送報文,服務器端接收報文,如果接收成功,從服務器端的角度來看:客戶端的報文接收能力以及服務器端的報文發送能力都符合預期。
經過三次握手的過程,客戶端和服務器端都明確對方以及自己能成功接收和發送信息,所以就可以開始正常通信。
2.4.2 假設如果只有兩次握手過程,是否能順利建立 TCP 連接?
《計算機網絡》 一書中對此進行了解釋,三次握手的目的是 "為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤"。
如果 TCP 只有兩次握手,如果服務器端發送的第一個請求建立連接的報文在某個網絡節點長時間阻塞,等到連接釋放之后才抵達服務器端。本來這是一個早就失效的報文,但是服務器端收到這個失效的請求建立連接報文之后,會誤以為是客戶端需要建立一個新的連接請求,于是向客戶端發送 ACK 確認報文,同意建立連接,這時候因為已經完成了兩次握手,所以新的連接就會建立成功,這種情況顯然不符合預期。
如果是三次握手,客戶端不會向服務器端發送 ACK 確認報文,所以服務器端超過最長等待時間后,會認為客戶端沒有要求建立請求,這個無效報文最終會失效。
3. 小結
本章節給大家介紹了 TCP 和 UDP 協議的報文格式以及區別,分析了 TCP 建立連接的握手過程,需要大家能夠準確畫出 TCP 握手每個過程的標志位以及序號、確認號,并且從原理上理解三次握手的必要性,下一章節會繼續給大家分析 TCP 四次揮手過程。