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