當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 程序員小灰
[導(dǎo)讀]你是一臺(tái)電腦,你的名字叫 A 只要你知道另一位伙伴 B 的 IP 地址,且你們之間的網(wǎng)絡(luò)是通的,無論多遠(yuǎn),你都可以將一個(gè)數(shù)據(jù)包發(fā)送給你的伙伴 B 這就是物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層這三層所做的事情。

你是一臺(tái)電腦,你的名字叫 A

只要你知道另一位伙伴 B 的 IP 地址,且你們之間的網(wǎng)絡(luò)是通的,無論多遠(yuǎn),你都可以將一個(gè)數(shù)據(jù)包發(fā)送給你的伙伴 B

這就是物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層這三層所做的事情。 站在第四層的你,就可以不要臉地利用下三層所做的鋪墊,隨心所欲地發(fā)送數(shù)據(jù),而不必?fù)?dān)心找不到對(duì)方了。

雖然你此時(shí)還什么都沒干,但你還是給自己這一層起了個(gè)響亮的名字,叫做傳輸層。 你本以為自己所在的第四層萬事大吉,啥事沒有,但很快問題就接踵而至。

問題來了

前三層協(xié)議只能把數(shù)據(jù)包從一個(gè)主機(jī)搬到另外一臺(tái)主機(jī),但是,到了目的地以后,數(shù)據(jù)包具體交給哪個(gè)程序(進(jìn)程)呢?

所以,你需要把通信的進(jìn)程區(qū)分開來,于是就給每個(gè)進(jìn)程分配一個(gè)數(shù)字編號(hào),你給它起了一個(gè)響亮的名字:端口號(hào)。

然后你在要發(fā)送的數(shù)據(jù)包上,增加了傳輸層的頭部,源端口號(hào)目標(biāo)端口號(hào)。


OK,這樣你將原本主機(jī)到主機(jī)的通信,升級(jí)為了進(jìn)程和進(jìn)程之間的通信 你沒有意識(shí)到,你不知不覺實(shí)現(xiàn)了 UDP 協(xié)議 (當(dāng)然 UDP 協(xié)議中不光有源端口和目標(biāo)端口,還有數(shù)據(jù)包長(zhǎng)度和校驗(yàn)值,我們暫且略過) 就這樣,你用 UDP 協(xié)議無憂無慮地同 B 進(jìn)行著通信,一直沒發(fā)生什么問題。

但很快,你發(fā)現(xiàn)事情變得非常復(fù)雜......

丟包問題

由于網(wǎng)絡(luò)的不可靠,數(shù)據(jù)包可能在半路丟失,而 A 和 B 卻無法察覺。

對(duì)于丟包問題,只要解決兩個(gè)事就好了。 第一個(gè),A 怎么知道包丟了? 答案:讓 B 告訴 A 第二個(gè),丟了的包怎么辦? 答案:重傳 于是你設(shè)計(jì)了如下方案,A 每發(fā)一個(gè)包,都必須收到來自 B 的確認(rèn)(ACK),再發(fā)下一個(gè),否則在一定時(shí)間內(nèi)沒有收到確認(rèn),就重傳這個(gè)包。

你管它叫停止等待協(xié)議。只要按照這個(gè)協(xié)議來,雖然 A 無法保證 B 一定能收到包,但 A 能夠確認(rèn) B 是否收到了包,收不到就重試,盡最大努力讓這個(gè)通信過程變得可靠,于是你們現(xiàn)在的通信過程又有了一個(gè)新的特征,可靠交付

效率問題

停止等待雖然能解決問題,但是效率太低了,A 原本可以在發(fā)完第一個(gè)數(shù)據(jù)包之后立刻開始發(fā)第二個(gè)數(shù)據(jù)包,但由于停止等待協(xié)議,A 必須等數(shù)據(jù)包到達(dá)了 B ,且 B 的 ACK 包又回到了 A,才可以繼續(xù)發(fā)第二個(gè)數(shù)據(jù)包,這效率慢得可不是一點(diǎn)兩點(diǎn)。 于是你對(duì)這個(gè)過程進(jìn)行了改進(jìn),采用流水線的方式,不再傻傻地等。

順序問題

但是網(wǎng)路是復(fù)雜的、不可靠的。 有的時(shí)候 A 發(fā)出去的數(shù)據(jù)包,分別走了不同的路由到達(dá) B,可能無法保證和發(fā)送數(shù)據(jù)包時(shí)一樣的順序。

在流水線中有多個(gè)數(shù)據(jù)包和ACK包在亂序流動(dòng),他們之間對(duì)應(yīng)關(guān)系就亂掉了。 難道還回到停止等待協(xié)議?A 每收到一個(gè)包的確認(rèn)(ACK)再發(fā)下一個(gè)包,那就根本不存在順序問題。應(yīng)該有更好的辦法! A 在發(fā)送的數(shù)據(jù)包中增加一個(gè)序號(hào)(seq),同時(shí) B 要在 ACK 包上增加一個(gè)確認(rèn)號(hào)(ack),這樣不但解決了停止等待協(xié)議的效率問題,也通過這樣標(biāo)序號(hào)的方式解決了順序問題。

而 B 這個(gè)確認(rèn)號(hào)意味深長(zhǎng):比如 B 發(fā)了一個(gè)確認(rèn)號(hào)為 ack = 3,它不僅僅表示 A 發(fā)送的序號(hào)為 2 的包收到了,還表示 2 之前的數(shù)據(jù)包都收到了。這種方式叫累計(jì)確認(rèn)累計(jì)應(yīng)答。

注意,實(shí)際上 ack 的號(hào)是收到的最后一個(gè)數(shù)據(jù)包的序號(hào) seq + 1,也就是告訴對(duì)方下一個(gè)應(yīng)該發(fā)的序號(hào)是多少。但圖中為了便于理解,ack 就表示收到的那個(gè)序號(hào),不必糾結(jié)。

流量問題

有的時(shí)候,A 發(fā)送數(shù)據(jù)包的速度太快,而 B 的接收能力不夠,但 B 卻沒有告知 A 這個(gè)情況。

怎么解決呢? 很簡(jiǎn)單,B 告訴 A 自己的接收能力,A 根據(jù) B 的接收能力,相應(yīng)控制自己的發(fā)送速率,就好了。 B 怎么告訴 A 呢?B 跟 A 說"我很強(qiáng)"這三個(gè)字么?那肯定不行,得有一個(gè)嚴(yán)謹(jǐn)?shù)囊?guī)范。 于是 B 決定,每次發(fā)送數(shù)據(jù)包給 A 時(shí),順帶傳過來一個(gè)值,叫窗口大小(win),這個(gè)值就表示 B 的接收能力。同理,每次 A 給 B 發(fā)包時(shí)也帶上自己的窗口大小,表示 A 的接收能力。

B 告訴了 A 自己的窗口大小值,A 怎么利用它去做 A 這邊發(fā)包的流量控制呢? 很簡(jiǎn)單,假如 B 給 A 傳過來的窗口大小 win = 5,那 A 根據(jù)這個(gè)值,把自己要發(fā)送的數(shù)據(jù)分成這么幾類。

圖片過于清晰,就不再文字解釋了。 當(dāng) A 不斷發(fā)送數(shù)據(jù)包時(shí),已發(fā)送的最后一個(gè)序號(hào)就往右移動(dòng),直到碰到了窗口的上邊界,此時(shí) A 就無法繼續(xù)發(fā)包,達(dá)到了流量控制。

但是當(dāng) A 不斷發(fā)包的同時(shí),A 也會(huì)收到來自 B 的確認(rèn)包,此時(shí)整個(gè)窗口會(huì)往右移動(dòng),因此上邊界也往右移動(dòng),A 就能發(fā)更多的數(shù)據(jù)包了。

以上都是在窗口大小不變的情況下,而 B 在發(fā)給 A 的 ACK 包中,每一個(gè)都可以重新設(shè)置一個(gè)新的窗口大小,如果 A 收到了一個(gè)新的窗口大小值,A 會(huì)隨之調(diào)整。 如果 A 收到了比原窗口值更大的窗口大小,比如 win = 6,則 A 會(huì)直接將窗口上邊界向右移動(dòng) 1 個(gè)單位。

如果 A 收到了比原窗口值小的窗口大小,比如 win = 4,則 A 暫時(shí)不會(huì)改變窗口大小,更不會(huì)將窗口上邊界向左移動(dòng),而是等著 ACK 的到來,不斷將左邊界向右移動(dòng),直到窗口大小值收縮到新大小為止。

OK,終于將流量控制問題解決得差不多了,你看著上面一個(gè)個(gè)小動(dòng)圖,給這個(gè)窗口起了一個(gè)更生動(dòng)的名字,滑動(dòng)窗口

擁塞問題

但有的時(shí)候,不是 B 的接受能力不夠,而是網(wǎng)絡(luò)不太好,造成了網(wǎng)絡(luò)擁塞。

擁塞控制與流量控制有些像,但流量控制是受 B 的接收能力影響,而擁塞控制是受網(wǎng)絡(luò)環(huán)境的影響。 擁塞控制的解決辦法依然是通過設(shè)置一定的窗口大小,只不過,流量控制的窗口大小是 B 直接告訴 A 的,而擁塞控制的窗口大小按理說就應(yīng)該是網(wǎng)絡(luò)環(huán)境主動(dòng)告訴 A。 但網(wǎng)絡(luò)環(huán)境怎么可能主動(dòng)告訴 A 呢?只能 A 單方面通過試探,不斷感知網(wǎng)絡(luò)環(huán)境的好壞,進(jìn)而確定自己的擁塞窗口的大小。

擁塞窗口大小的計(jì)算有很多復(fù)雜的算法,就不在本文中展開了,假如擁塞窗口的大小為  cwnd,上一部分流量控制的滑動(dòng)窗口的大小為 rwnd,那么窗口的右邊界受這兩個(gè)值共同的影響,需要取它倆的最小值。 窗口大小 = min(cwnd, rwnd) 含義很容易理解,當(dāng) B 的接受能力比較差時(shí),即使網(wǎng)絡(luò)非常通暢,A 也需要根據(jù) B 的接收能力限制自己的發(fā)送窗口。當(dāng)網(wǎng)絡(luò)環(huán)境比較差時(shí),即使 B 有很強(qiáng)的接收能力,A 也要根據(jù)網(wǎng)絡(luò)的擁塞情況來限制自己的發(fā)送窗口。正所謂受其短板的影響嘛~

連接問題

有的時(shí)候,B 主機(jī)的相應(yīng)進(jìn)程還沒有準(zhǔn)備好或是掛掉了,A 就開始發(fā)送數(shù)據(jù)包,導(dǎo)致了浪費(fèi)。

這個(gè)問題在于,A 在跟 B 通信之前,沒有事先確認(rèn) B 是否已經(jīng)準(zhǔn)備好,就開始發(fā)了一連串的信息。就好比你和另一個(gè)人打電話,你還沒有"喂"一下確認(rèn)對(duì)方有沒有在聽,你就巴拉巴拉說了一堆。 這個(gè)問題該怎么解決呢? 地球人都知道,三次握手嘛!

A:我準(zhǔn)備好了(SYN)

B:我知道了(ACK),我也準(zhǔn)備好了(SYN)

A:我知道了(ACK)


A 與 B 各自在內(nèi)存中維護(hù)著自己的狀態(tài)變量,三次握手之后,雙方的狀態(tài)都變成了連接已建立(ESTABLISHED)。 雖然就只是發(fā)了三次數(shù)據(jù)包,并且在各自的內(nèi)存中維護(hù)了狀態(tài)變量,但這么說總覺得太 low,你看這個(gè)過程相當(dāng)于雙方建立連接的過程,于是你靈機(jī)一動(dòng),就叫它面向連接吧。 注意:這個(gè)連接是虛擬的,是由 A 和 B 這兩個(gè)終端共同維護(hù)的,在網(wǎng)絡(luò)中的設(shè)備根本就不知道連接這回事兒! 但凡事有始就有終,有了建立連接的過程,就要考慮釋放連接的過程,又是地球人都知道,四次揮手嘛!

A:再見,我要關(guān)閉了(FIN)

B:我知道了(ACK)

給 B 一段時(shí)間把自己的事情處理完...

B:再見,我要關(guān)閉了(FIN)

A:我知道了(ACK)



總結(jié)

以上講述的,就是 TCP 協(xié)議的核心思想,上面過程中需要傳輸?shù)男畔?,就體現(xiàn)在 TCP 協(xié)議的頭部,這里放上最常見的 TCP 協(xié)議頭解讀的圖。

不知道你現(xiàn)在再看下面這句話,是否能理解: TCP 是 面向連接的、可靠的、基于字節(jié)流的 傳輸層通信協(xié)議 面向連接、可靠,這兩個(gè)詞通過上面的講述很容易理解,那什么叫做基于字節(jié)流呢? 很簡(jiǎn)單,TCP 在建立連接時(shí),需要告訴對(duì)方 MSS(最大報(bào)文段大?。?/span> 也就是說,如果要發(fā)送的數(shù)據(jù)很大,在 TCP 層是需要按照 MSS 來切割成一個(gè)個(gè)的 TCP 報(bào)文段 的。 切割的時(shí)候我才不管你原來的數(shù)據(jù)表示什么意思,需要在哪里斷句啥的,我就把它當(dāng)成一串毫無意義的字節(jié),在我想要切割的地方咔嚓就來一刀,標(biāo)上序號(hào),只要接收方再根據(jù)這個(gè)序號(hào)拼成最終想要的完整數(shù)據(jù)就行了。 在我 TCP 傳輸這里,我就把它當(dāng)做一個(gè)個(gè)的字節(jié),也就是基于字節(jié)流的含義了。

最后留給大家一個(gè)作業(yè),模擬 A 與 B 建立一個(gè) TCP 連接。

第一題:A 給 B 發(fā)送 "aaa" ,然后 B 給 A 回復(fù)一個(gè)簡(jiǎn)單的字符串 "success",并將此過程抓包。

第二題:A 給 B 發(fā)送 "aaaaaa ... a" 超過最大報(bào)文段大小,然后 B 給 A 回復(fù)一個(gè)簡(jiǎn)單的字符串 "success",并將此過程抓包。

下面是我抓的包(第二題)

三次握手階段

A -> B [SYN] Seq=0 Win=64240 Len=0

MSS=1460 WS=256

B - >A [SYN, ACK] Seq=0 Ack=1 Win=29200 Len=0

MSS=1424 WS=512

A -> B [ACK] Seq=1 Ack=1 Win=132352 Len=0

數(shù)據(jù)發(fā)送階段

A -> B [ACK] Seq=1 Ack=1 Win=132352 Len=1424

A -> B [ACK] Seq=1425 Ack=1 Win=132352 Len=1424

A -> B [PSH, ACK] Seq=2849 Ack=1 Win=132352 Len=1247

B -> A [ACK] Seq=1 Ack=1425 Win=32256 Len=0

B -> A [ACK] Seq=1 Ack=2849 Win=35328 Len=0

B -> A [ACK] Seq=1 Ack=4096 Win=37888 Len=0

B -> A [PSH, ACK] Seq=1 Ack=4096 Win=37888 Len=7

四次揮手階段

B -> A [FIN, ACK] Seq=8 Ack=4096 Win=37888 Len=0

A -> B [ACK] Seq=4096 Ack=9 Win=132352 Len=0

A -> B [FIN, ACK] Seq=4096 Ack=9 Win=132352 Len=0(下面少?gòu)?fù)制了一行ACK,抱歉)
后記
一提到 TCP,可能很多人都想起被三次握手和四次揮手所支配的恐懼。但其實(shí)你跟著文中的思路你就會(huì)發(fā)現(xiàn),三次握手與四次揮手只占 TCP 所解決的核心問題中很小的一部分,只是因?yàn)樗诿嬖囍泻苓m合作為知識(shí)點(diǎn)進(jìn)行考察,所以在很多人的印象中就好像 TCP 的核心就是握手和揮手似的。
本文希望你能從問題出發(fā),真正理解 TCP 所想要解決的問題,你會(huì)發(fā)現(xiàn)很多原理就好像生活常識(shí)一樣順其自然,并不復(fù)雜,希望你有收獲~


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉