自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

TCP 和 UDP 的愛恨情仇

網(wǎng)絡(luò) 通信技術(shù)
TCP 和 UDP 在效率、報(bào)文段、流量控制、連接管理上均存在差異,由于這些差異導(dǎo)致了應(yīng)用場景要有不同的選擇,由于 TCP 每個包都需要進(jìn)行確認(rèn),因此 TCP 不適合告訴傳輸數(shù)據(jù)的場景,像是這種場景使用 UDP 就好了;像是 Ping 和 DNS Lookup,這類型的操作只需要一次簡單的請求/返回,不需要建立連接,用 UDP 就足夠了。

最近石家莊橋西區(qū) yq 比較嚴(yán)重,上周我封在了公司三天,洗漱吃飯都成問題,好不容易從公司申請回家到現(xiàn)在又封控一周了,每天游離在各種 app 、微信群的搶菜環(huán)節(jié),真的是搶而不是買,家樂福超市商品上線兩分鐘瞬間秒沒,我都不知道這群人是怎么搶菜的,難道都是圈里人?還有每天無窮無盡的核酸檢測,讓人無奈且頭疼,每天兩位數(shù)的陽性新增讓人麻木且看不到希望。今天剛接到通知,說是你可以出單元門活動活動筋骨了 ......

說點(diǎn)好的:?

寫了很多篇關(guān)于 TCP 和 UDP 的文章,還沒有好好聊過這兩個協(xié)議的區(qū)別,這篇我們就來談一談這個問題。

關(guān)于 TCP 和 UDP ,想必大家都看過一張這樣的圖。

圖片

有一個小姑娘在對著瓶口慢慢喝水,下面寫著可靠的傳輸,少女的衣服沒有被水浸濕,這張圖被稱為 TCP 。

然后又有一個小姑娘在舉著水瓶以很快的速度向下倒水,少女的頭發(fā)凌亂,臉色泛紅,衣服也被水浸濕,這張圖被稱為 UDP 。

這兩張圖我認(rèn)為是個程序員都能大致總結(jié)出來這兩個傳輸協(xié)議的不同點(diǎn)(畢竟圖上都寫的很清楚了)甚至不少同學(xué)對 UDP 產(chǎn)生了邪惡的念想,你說作者好好的畫個圖不行嗎,非要在臉上掛個紅,把衣服弄濕了才行。。。。。。。

咳,咱們言歸正傳,TCP 和 UDP 的區(qū)別一直是面試的重點(diǎn),也是經(jīng)常被用來拿來各種比較的兩個協(xié)議。

建立連接的差異

TCP 建立連接需要經(jīng)過三次握手,同時 TCP 斷開連接需要經(jīng)過四次揮手,這也表示 TCP 是一種面向連接的協(xié)議,這個連接不是用一條網(wǎng)線或者一個管道把兩個通信雙方綁在一起,而是建立一條虛擬通信管道。

TCP 的三次握手流程(客戶端向服務(wù)器發(fā)送建立連接請求):

圖片

  • 服務(wù)端進(jìn)程準(zhǔn)備好接收來自外部的 TCP 連接,一般情況下是調(diào)用 bind、listen、socket 三個函數(shù)完成。這種打開方式被認(rèn)為是被動打開(passive open)?。然后服務(wù)端進(jìn)程處于LISTEN 狀態(tài),等待客戶端連接請求。
  • 客戶端通過connect? 發(fā)起主動打開(active open)?,向服務(wù)器發(fā)出連接請求,請求中首部同步位 SYN = 1,同時選擇一個初始序號 sequence ,簡寫 seq = x。SYN 報(bào)文段不允許攜帶數(shù)據(jù),只消耗一個序號。此時,客戶端進(jìn)入SYN-SEND 狀態(tài)。
  • 服務(wù)器收到客戶端連接后,需要確認(rèn)客戶端的報(bào)文段。在確認(rèn)報(bào)文段中,把 SYN 和 ACK 位都置為 1 。確認(rèn)號是 ack = x + 1,同時也為自己選擇一個初始序號 seq = y。請注意,這個報(bào)文段也不能攜帶數(shù)據(jù),但同樣要消耗掉一個序號。此時,TCP 服務(wù)器進(jìn)入SYN-RECEIVED(同步收到) 狀態(tài)。
  • 客戶端在收到服務(wù)器發(fā)出的響應(yīng)后,需要給出確認(rèn)連接。確認(rèn)連接中的 ACK 置為 1 ,序號為 seq = x + 1,確認(rèn)號為 ack = y + 1。TCP 規(guī)定,這個報(bào)文段可以攜帶數(shù)據(jù)也可以不攜帶數(shù)據(jù),如果不攜帶數(shù)據(jù),那么下一個數(shù)據(jù)報(bào)文段的序號仍是 seq = x + 1。這時,客戶端進(jìn)入ESTABLISHED (已連接) 狀態(tài)。
  • 服務(wù)器收到客戶的確認(rèn)后,也進(jìn)入ESTABLISHED 狀態(tài)。

而 UDP 是面向數(shù)據(jù)報(bào)的協(xié)議,所以 UDP 壓根不會有連接的概念,也就不會有三次握手建立連接的過程。

數(shù)據(jù)傳輸結(jié)束后,通信雙方可以釋放連接。數(shù)據(jù)傳輸結(jié)束后的客戶端主機(jī)和服務(wù)端主機(jī)都處于 ESTABLISHED 狀態(tài),然后進(jìn)入釋放連接的過程。

(客戶端主機(jī)主動關(guān)閉連接)

圖片

TCP 斷開連接需要?dú)v經(jīng)的過程如下:

  • 客戶端應(yīng)用程序發(fā)出釋放連接的報(bào)文段,并停止發(fā)送數(shù)據(jù),主動關(guān)閉 TCP 連接。客戶端主機(jī)發(fā)送釋放連接的報(bào)文段,報(bào)文段中首部 FIN 位置為 1 ,不包含數(shù)據(jù),序列號位 seq = u,此時客戶端主機(jī)進(jìn)入 FIN-WAIT-1(終止等待 1) 階段。
  • 服務(wù)器主機(jī)接收到客戶端發(fā)出的報(bào)文段后,即發(fā)出確認(rèn)應(yīng)答報(bào)文,確認(rèn)應(yīng)答報(bào)文中 ACK = 1,生成自己的序號位 seq = v,ack = u + 1,然后服務(wù)器主機(jī)就進(jìn)入 CLOSE-WAIT(關(guān)閉等待) 狀態(tài),這個時候客戶端主機(jī) -> 服務(wù)器主機(jī)這條方向的連接就釋放了,客戶端主機(jī)沒有數(shù)據(jù)需要發(fā)送,此時服務(wù)器主機(jī)是一種半連接的狀態(tài),但是服務(wù)器主機(jī)仍然可以發(fā)送數(shù)據(jù)。
  • 客戶端主機(jī)收到服務(wù)端主機(jī)的確認(rèn)應(yīng)答后,即進(jìn)入 FIN-WAIT-2(終止等待2) 的狀態(tài)。等待客戶端發(fā)出連接釋放的報(bào)文段。
  • 當(dāng)服務(wù)器主機(jī)沒有數(shù)據(jù)發(fā)送后,應(yīng)用進(jìn)程就會通知 TCP 釋放連接。這時服務(wù)端主機(jī)會發(fā)出斷開連接的報(bào)文段,報(bào)文段中 ACK = 1,序列號 seq = w,因?yàn)樵谶@之間可能已經(jīng)發(fā)送了一些數(shù)據(jù),所以 seq 不一定等于 v + 1。ack = u + 1,在發(fā)送完斷開請求的報(bào)文后,服務(wù)端主機(jī)就進(jìn)入了 LAST-ACK(最后確認(rèn))的階段。
  • 客戶端收到服務(wù)端的斷開連接請求后,客戶端需要作出響應(yīng),客戶端發(fā)出斷開連接的報(bào)文段,在報(bào)文段中,ACK = 1, 序列號 seq = u + 1,因?yàn)榭蛻舳藦倪B接開始斷開后就沒有再發(fā)送數(shù)據(jù),ack = w + 1,然后進(jìn)入到 TIME-WAIT(時間等待)? 狀態(tài),請注意,這個時候 TCP 連接還沒有釋放。必須經(jīng)過時間等待的設(shè)置,也就是 2MSL? 后,客戶端才會進(jìn)入 CLOSED? 狀態(tài),時間 MSL 叫做最長報(bào)文段壽命(Maximum Segment Lifetime)。
  • 服務(wù)端主要收到了客戶端的斷開連接確認(rèn)后,就會進(jìn)入 CLOSED 狀態(tài)。因?yàn)榉?wù)端結(jié)束 TCP 連接時間要比客戶端早,而整個連接斷開過程需要發(fā)送四個報(bào)文段,因此釋放連接的過程也被稱為四次揮手。

UDP 不存在這條連接,所以它也不需要四次揮手操作。

所以總結(jié)一點(diǎn):TCP 是面向連接的,它的數(shù)據(jù)傳輸前需要維護(hù)一條虛擬連接,數(shù)據(jù)傳輸需要在這條虛擬連接上進(jìn)行,數(shù)據(jù)傳輸完畢后需要斷開這條連接,而 UDP 傳輸不是面向連接的,UDP 發(fā)送數(shù)據(jù)不會建立連接,也不會關(guān)心接收端的狀態(tài)。

可靠性的差異

TCP 和 UDP 一個主要拿來作對比的就是可靠性,TCP 是一種可靠性的傳輸層協(xié)議,UDP 是一種不可靠的傳輸層協(xié)議。TCP 的這種可靠性主要由下面這些特征來保證:

通過序列號和應(yīng)答號實(shí)現(xiàn)可靠性

計(jì)算機(jī)網(wǎng)絡(luò)主機(jī)之間的相互通信非常類似于我們?nèi)粘I钪袃蓚€人之間打電話,這種對話通常是一問一答形式,如果你講了一句話并沒有收到任何回應(yīng),你通常需要再說一次來確保對方是否聽到,如果對方給你回應(yīng)了一句話,就說明他已經(jīng)聽到你的講話了,這就是一個完整的通話流程(拋開建立連接不談,我們著重點(diǎn)放在建立連接之后)。

"對方給你的響應(yīng)" 在計(jì)算機(jī)網(wǎng)絡(luò)中被稱為確認(rèn)應(yīng)答(ACK)?,TCP 就是通過 ACK 來實(shí)現(xiàn)可靠的數(shù)據(jù)傳輸,也就是說,發(fā)送方在發(fā)出請求之后會等待目標(biāo)主機(jī)的響應(yīng),如果沒有收到響應(yīng),發(fā)送方在經(jīng)過一段時間后就會重傳請求。所以,即使在發(fā)送過程中產(chǎn)生丟包,TCP 仍然能夠通過重傳來實(shí)現(xiàn)可靠性。

圖片

上面描述的情況屬于發(fā)送方請求丟失,還有一種情況屬于響應(yīng)丟失,也就是說請求發(fā)送到目標(biāo)主機(jī)后,目標(biāo)主機(jī)會發(fā) ACK 給請求方,這個 ACK 也有可能丟失,如果 ACK 在鏈路中丟失,一段時間后請求方?jīng)]有收到目標(biāo)主機(jī)的 ACK ,仍然會選擇重傳未收到 ACK 的這個請求。

圖片

除了消息丟失之外,還存在一種延遲到達(dá)的現(xiàn)象,延遲到達(dá)指的是發(fā)送方發(fā)送一個報(bào)文段之后,這個報(bào)文也許是由于網(wǎng)絡(luò)抖動或者網(wǎng)絡(luò)擁堵導(dǎo)致一個報(bào)文段遲遲沒有到達(dá)目標(biāo)主機(jī),或者目標(biāo)主機(jī)的響應(yīng) ACK 遲遲沒有到達(dá)發(fā)送方的現(xiàn)象。這個一段時間判斷的標(biāo)準(zhǔn)就是重傳時間,一旦過了重傳時間發(fā)送方會重傳報(bào)文段,很可能存在重傳報(bào)文段到達(dá)之后,第一次發(fā)送的報(bào)文段才剛到的情況,這就存在一個問題:目標(biāo)主機(jī)收到了兩個相同的報(bào)文段。必須選擇一個報(bào)文段進(jìn)行丟棄,但是應(yīng)該選擇哪個報(bào)文段呢?

可以通過序列號(seq)來實(shí)現(xiàn),序列號是按照順序給發(fā)送數(shù)據(jù)的每一個字節(jié)都標(biāo)上號碼的編號。接收端通過查詢 TCP 首部中的序列號和數(shù)據(jù)的長度,將自己下一步應(yīng)該接收的序列號作為確認(rèn)應(yīng)答返送回去。通過序列號和確認(rèn)應(yīng)答號,TCP 能夠識別是否已經(jīng)接收數(shù)據(jù),又能夠判斷是否需要接收,從而實(shí)現(xiàn)可靠傳輸。

圖片

如上圖所示,請求按照順序發(fā)送的話是 seq = 1 ,這個請求會把第 1 字節(jié)到第 n 字節(jié)的數(shù)據(jù)一起發(fā)送過去,等待目標(biāo)主機(jī)一次確認(rèn)每個字節(jié)后,再發(fā)送 seq = n + 1 的請求,確認(rèn)完成后再發(fā)送 seq = m + 1 的請求,這樣能夠保證序列號不會重復(fù)。

UDP 沒有所謂的序列號和確認(rèn)號,所以不會對數(shù)據(jù)進(jìn)行確認(rèn),數(shù)據(jù)丟失后也不會進(jìn)行重傳,所以 UDP 是一種不可靠的協(xié)議。

如果使用 TCP 和 UDP 來比喻開發(fā)人員:TCP 就是那種凡事都要設(shè)計(jì)好,沒設(shè)計(jì)不會進(jìn)行開發(fā)的工程師,需要把一切因素考慮在內(nèi)后再開干!所以非??孔V?;而 UDP 就是那種上來直接干干干,接到項(xiàng)目需求馬上就開干,也不管設(shè)計(jì),也不管技術(shù)選型,就是干,這種開發(fā)人員非常不靠譜,但是適合快速迭代開發(fā),因?yàn)榭梢择R上上手!

有序性差異

我們上面說到,TCP 會對請求分開發(fā)送,每次請求所攜帶的數(shù)據(jù)都會被目標(biāo)主機(jī)進(jìn)行確認(rèn),目標(biāo)主機(jī)依次確認(rèn)每個請求后,就會對請求中的數(shù)據(jù)進(jìn)行重組,由于請求是由 seq 的,所以 TCP 在重組這些數(shù)據(jù)時,也會按照順序進(jìn)行重組,而 UDP 沒有有序性的這種保證。

報(bào)文段的差異

TCP 和 UDP 同屬于傳輸層協(xié)議,傳輸層協(xié)議傳輸?shù)臄?shù)據(jù)統(tǒng)稱為報(bào)文段,TCP 和 UDP 的報(bào)文段的主要差異如下。

UDP 報(bào)文段結(jié)構(gòu)

圖片

  • 源端口號(Source Port) :這個字段占據(jù) UDP 報(bào)文頭的前 16 位,通常包含發(fā)送數(shù)據(jù)報(bào)的應(yīng)用程序所使用的 UDP 端口。接收端的應(yīng)用程序利用這個字段的值作為發(fā)送響應(yīng)的目的地址。這個字段是可選項(xiàng),有時不會設(shè)置源端口號。沒有源端口號就默認(rèn)為 0 ,通常用于不需要返回消息的通信中。
  • 目標(biāo)端口號(Destination Port): 表示接收端端口,字段長為 16 位。
  • 長度(Length): 該字段占據(jù) 16 位,表示 UDP 數(shù)據(jù)報(bào)長度,包含 UDP 報(bào)文頭和 UDP 數(shù)據(jù)長度。因?yàn)?UDP 報(bào)文頭長度是 8 個字節(jié),所以這個值最小為 8,最大長度為 2 ^ 16 = 65535 字節(jié)。
  • 校驗(yàn)和(Checksum):UDP 使用校驗(yàn)和來保證數(shù)據(jù)安全性,UDP 的校驗(yàn)和也提供了差錯檢測功能,差錯檢測用于校驗(yàn)報(bào)文段從源到目標(biāo)主機(jī)的過程中,數(shù)據(jù)的完整性是否發(fā)生了改變。

TCP 報(bào)文段結(jié)構(gòu)

圖片

TCP 報(bào)文段結(jié)構(gòu)相比 UDP 報(bào)文結(jié)構(gòu)多了很多內(nèi)容。但是前兩個 32 比特的字段是一樣的。它們是 源端口號? 和 目標(biāo)端口號?。另外,和 UDP 一樣,TCP 也包含校驗(yàn)和(checksum field) ,除此之外,TCP 報(bào)文段首部還有下面這些

  • 32 比特的序號字段(sequence number field)? 和 32 比特的確認(rèn)號字段(acknowledgment number field) 。這些字段被 TCP 發(fā)送方和接收方用來實(shí)現(xiàn)可靠的數(shù)據(jù)傳輸。
  • 4 比特的首部字段長度字段(header length field),這個字段指示了以 32 比特的字為單位的 TCP 首部長度。TCP 首部的長度是可變的,但是通常情況下,選項(xiàng)字段為空,所以 TCP 首部字段的長度是 20 字節(jié)。
  • 16 比特的 接受窗口字段(receive window field) ,這個字段用于流量控制。它用于指示接收方能夠/愿意接受的字節(jié)數(shù)量
  • 可變的選項(xiàng)字段(options field),這個字段用于發(fā)送方和接收方協(xié)商最大報(bào)文長度,也就是 MSS 時使用
  • 6 比特的 標(biāo)志字段(flag field)?, ACK? 標(biāo)志用于指示確認(rèn)字段中的值是有效的,這個報(bào)文段包括一個對已被成功接收報(bào)文段的確認(rèn);RST、SYN、FIN? 標(biāo)志用于連接的建立和關(guān)閉;CWR? 和 ECE? 用于擁塞控制;PSH? 標(biāo)志用于表示立刻將數(shù)據(jù)交給上層處理;URG? 標(biāo)志用來表示數(shù)據(jù)中存在需要被上層處理的 緊急 數(shù)據(jù)。緊急數(shù)據(jù)最后一個字節(jié)由 16 比特的緊急數(shù)據(jù)指針字段(urgeent data pointer field) 指出。一般情況下,PSH 和 URG 并沒有使用。

所以從報(bào)文段結(jié)構(gòu)的對比可以看出,TCP 相比 UDP 多了許多 Flags、序號和確認(rèn)號,這些都屬于 TCP 的連接控制。除此之外還有接收窗口,這些屬于擁塞控制和流量控制的內(nèi)容。TCP 的首部開銷要比 UDP 大,因?yàn)?TCP 首部固定有 20 字節(jié),UDP 首部固定才 8 字節(jié)。TCP 和 UDP 都提供了數(shù)據(jù)校驗(yàn)功能。

效率的差異

TCP 報(bào)文段的發(fā)送采用的是"一問一答"形式的,每個請求都會被目標(biāo)主機(jī)確認(rèn)后再發(fā)送下一條報(bào)文,效率很慢,后來為了解決這個問題,TCP 引入了 窗口 這個概念,即使在往返時間較長、頻次很多的情況下,它也能控制網(wǎng)絡(luò)性能的下降。

我們之前每次請求發(fā)送都是以報(bào)文段的形式進(jìn)行的,引入窗口后,每次請求都可以發(fā)送多個報(bào)文段,也就是說一個窗口可以發(fā)送多個報(bào)文段。窗口大小就是指無需等待確認(rèn)應(yīng)答就可以繼續(xù)發(fā)送報(bào)文段的最大值。

在這個窗口機(jī)制中,大量使用了 緩沖區(qū) ,通過對多個段同時進(jìn)行確認(rèn)應(yīng)答的功能。

如下圖所示,發(fā)送報(bào)文段中高亮部分即是我們提到的窗口,在窗口內(nèi),即使沒有收到確認(rèn)應(yīng)答也可以把請求發(fā)送出去。不過,在整個窗口的確認(rèn)應(yīng)答沒有到達(dá)之前,如果部分報(bào)文段丟失,那么發(fā)送方將仍會重傳。為此,發(fā)送方需要設(shè)置緩存來保留這些需要重傳的報(bào)文段,直到收到他們的確認(rèn)應(yīng)答。

圖片

在滑動窗口以外的部分是尚未發(fā)送的報(bào)文段和已經(jīng)接收到的報(bào)文段,如果報(bào)文段已經(jīng)收到確認(rèn)則不可進(jìn)行重發(fā),此時報(bào)文段就可以從緩沖區(qū)中清除。

在收到確認(rèn)的情況下,會將窗口滑動到確認(rèn)應(yīng)答中確認(rèn)號的位置,如上圖所示,這樣可以順序?qū)⒍鄠€段同時發(fā)送,用以提高通信性能,這種窗口也叫做 滑動窗口(Sliding window)。

UDP 發(fā)送的報(bào)文段不需要確認(rèn),也就沒有窗口的概念,所以 UDP 傳輸效率比較高。

使用場景的差異

TCP 和 UDP 在效率、報(bào)文段、流量控制、連接管理上均存在差異,由于這些差異導(dǎo)致了應(yīng)用場景要有不同的選擇,由于 TCP 每個包都需要進(jìn)行確認(rèn),因此 TCP 不適合告訴傳輸數(shù)據(jù)的場景,像是這種場景使用 UDP 就好了;像是 Ping 和 DNS Lookup,這類型的操作只需要一次簡單的請求/返回,不需要建立連接,用 UDP 就足夠了。比如 HTTP 協(xié)議需要考慮請求響應(yīng)的可靠性,這種場景應(yīng)該使用 TCP 協(xié)議,但是像 HTTP 3.0 這類應(yīng)用層協(xié)議,從功能性上思考,暫時沒有找到太多的優(yōu)化點(diǎn),但是想要把網(wǎng)絡(luò)優(yōu)化到極致,就會用 UDP 作為底層技術(shù),然后在 UDP 基礎(chǔ)上解決可靠性。

責(zé)任編輯:武曉燕 來源: 程序員cxuan
相關(guān)推薦

2025-01-03 09:39:04

2022-05-13 09:47:28

Docker容器

2021-04-12 06:08:16

HiveSpark大數(shù)據(jù)

2019-05-15 15:10:12

Tomcat Session Cookie

2020-11-24 10:13:20

測試開發(fā)管理

2024-08-07 08:22:27

2024-06-05 11:06:22

Go語言工具

2024-06-07 00:09:50

2025-01-13 00:00:35

2020-04-09 15:26:55

間諜軟件NSOFacebook

2022-05-07 07:43:07

Redis存儲系統(tǒng)數(shù)據(jù)庫

2013-02-20 10:00:16

微軟CodePlexGitHub

2021-06-16 06:48:06

接口微信

2015-11-24 15:13:15

2024-03-11 09:37:01

模型圖片編輯

2019-12-31 20:41:39

IPUDPTCP

2015-11-05 09:55:40

SDNNFV

2020-05-27 14:07:21

蜂窩廣域網(wǎng)局域物聯(lián)網(wǎng)物聯(lián)網(wǎng)

2020-06-16 15:48:40

蘋果英特爾芯片

2010-07-06 15:50:12

TCP和UDP協(xié)議
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號