TCP協(xié)議簡(jiǎn)單了解
TCP(Transmission Control Protocol,傳輸控制協(xié)議),它是最常用傳輸層協(xié)議,也是最穩(wěn)定傳輸層協(xié)議,很多上層應(yīng)用都是依賴于TCP進(jìn)程傳輸數(shù)據(jù)。
TCP 屬于傳輸層協(xié)議,它為應(yīng)用層提供了可靠的字節(jié)流服務(wù)。在網(wǎng)絡(luò)協(xié)議棧中對(duì)它的描述要比對(duì)其它協(xié)議的描述復(fù)雜的多,這也導(dǎo)致了lwip中很大一部分代碼都是用于描述TCP協(xié)議的。
IP包暢游在網(wǎng)絡(luò)中,從主機(jī)A出發(fā),風(fēng)塵仆仆趕到主機(jī)B,雖然整個(gè)過(guò)程占用時(shí)間都是以毫秒或者秒計(jì)算的,但期間風(fēng)險(xiǎn)重重啊,可能發(fā)生的情況:IP包在行進(jìn)中因擁塞而被路由器、交換機(jī)拋棄,以至于IP包在傳輸期間可能會(huì)被丟掉。但主機(jī)A會(huì)希望所有的IP包都安全地抵達(dá)主機(jī)B,這需要一個(gè)機(jī)制來(lái)保障數(shù)據(jù)能穩(wěn)定傳輸,于是專家們制定了TCP傳輸協(xié)議。
TCP是面向連接的技術(shù)。也就是說(shuō),基于TCP的兩臺(tái)主機(jī),在通信之前要先建立信息交互(IP協(xié)議則沒(méi)有這種交互),主機(jī)之間的設(shè)備(路由器)和線路,都僅是只負(fù)責(zé)處理協(xié)議棧模型的下三層(物理層、數(shù)據(jù)鏈路層和網(wǎng)絡(luò)層)的工作。
TCP一旦發(fā)現(xiàn)傳輸出錯(cuò)就會(huì)重新傳輸數(shù)據(jù)包,直到所有數(shù)據(jù)安全、正確地傳送到目的地,再遞交到應(yīng)用層。
- TCP屬于傳輸模型的傳輸層
- TCP采用數(shù)據(jù)流的形式傳輸
- TCP提供可靠地、面向連接和字節(jié)流的傳輸層服務(wù)
TCP協(xié)議的特性
面向連接
TCP
是一個(gè)面向連接的協(xié)議,無(wú)論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一個(gè)連接,否則將無(wú)法發(fā)送數(shù)據(jù),一個(gè)TCP連接必須有雙方 IP
地址與端口號(hào),而面向連接意味著兩個(gè)使用 TCP
的應(yīng)用(通常是一個(gè)客戶端和一個(gè)服務(wù)器端)。就像打電話一樣。
正面確認(rèn)
當(dāng)TCP協(xié)議發(fā)出一個(gè)TCP報(bào)文段后,它啟動(dòng)一個(gè)定時(shí)器,等待目的端主機(jī) 確認(rèn)
收到這個(gè)報(bào)文段,如果不能及時(shí)收到一個(gè)確認(rèn),將重發(fā)這個(gè)報(bào)文段。一個(gè)完整的TCP傳輸必須有兩個(gè)端的主機(jī)進(jìn)行數(shù)據(jù)的交互,接收方在接收到數(shù)據(jù)之后必須正面進(jìn)行確認(rèn),向發(fā)送方報(bào)告接收的結(jié)果。
因?yàn)門CP協(xié)議依賴的是IP層的服務(wù),IP數(shù)據(jù)報(bào)的傳輸是無(wú)連接、不可靠的,因此它要通過(guò)確認(rèn)來(lái)知道接收方確實(shí)已經(jīng)收到數(shù)據(jù)了。
數(shù)據(jù)分割
應(yīng)用數(shù)據(jù)會(huì)被分割成TCP協(xié)議認(rèn)為最適合發(fā)送的報(bào)文段,這些其實(shí)是動(dòng)態(tài)調(diào)整的, TCP
協(xié)議只能是盡可能發(fā)送最大報(bào)文段(MSS)以保證數(shù)據(jù)傳輸?shù)乃俾省?/p>
數(shù)據(jù)緩沖
在發(fā)送方想要發(fā)送數(shù)據(jù)的時(shí)候,由于應(yīng)用程序的數(shù)據(jù)大小、類型都是不可預(yù)估的,而 TCP
提供了緩沖機(jī)制來(lái)處理這些數(shù)據(jù),實(shí)際上TCP協(xié)議發(fā)送數(shù)據(jù)時(shí),如果數(shù)據(jù)還未到 TCP
報(bào)文段合適的大小,這些數(shù)據(jù)可能會(huì)被臨時(shí)緩存,知道超時(shí)或者等待到數(shù)據(jù)合適到TCP報(bào)文段時(shí)才發(fā)送出去,這也是大名鼎鼎的 Nagle
算法(當(dāng)然可以禁用它哈哈哈)。這樣就能保證一次傳輸數(shù)據(jù)的效率并且減少網(wǎng)絡(luò)中的流量。
發(fā)送方在將數(shù)據(jù)發(fā)送出去后并不會(huì) 立即
刪除數(shù)據(jù),而是讓數(shù)據(jù)依舊保存在緩沖區(qū)中(實(shí)際上是使用鏈表維護(hù)的),因?yàn)榘l(fā)送出去的數(shù)據(jù)不一定能被接收方正確接收,它需要等待到接收方的確認(rèn)再將數(shù)據(jù)刪除。
同樣的,在接收方也需要有同樣的緩沖機(jī)制,因?yàn)?TCP
協(xié)議是以字節(jié)流發(fā)送數(shù)據(jù)的,這些數(shù)據(jù)可能會(huì)分割成多個(gè) TCP
報(bào)文段,而且在網(wǎng)絡(luò)中傳輸?shù)母鱾€(gè) TCP
報(bào)文段到達(dá)目標(biāo)主機(jī)的時(shí)間可能是不一樣的,這就導(dǎo)致數(shù)據(jù)失序,接收方需要把這些數(shù)據(jù)報(bào)組裝成完整且有序的數(shù)據(jù),然后再遞交到應(yīng)用層中,在這之前的數(shù)據(jù)都會(huì)被緩存。此外還有可能導(dǎo)致接收方接收到重復(fù)的數(shù)據(jù),因?yàn)镮P數(shù)據(jù)報(bào)會(huì)可能發(fā)生重復(fù),這就必須在接收方將重復(fù)的數(shù)據(jù)剔除。
全雙工通信
在 TCP
連接建立后,任何一個(gè)主機(jī)都可以向另一個(gè)主機(jī)發(fā)送數(shù)據(jù),數(shù)據(jù)是雙向流通的。在實(shí)際情況中,很大一部分的 TCP
的確認(rèn)是通過(guò) 捎帶
的方式來(lái)實(shí)現(xiàn),即接收方把確認(rèn)信息放到發(fā)送給發(fā)送方的報(bào)文段中,不必單獨(dú)為確認(rèn)信息申請(qǐng)一個(gè)報(bào)文。
當(dāng)然斷開(kāi)連接也是一樣的,任意一方都可以主動(dòng)斷開(kāi),不過(guò)對(duì)于服務(wù)器來(lái)說(shuō),應(yīng)用程序一般不會(huì)主動(dòng)斷開(kāi) TCP
連接,這其實(shí)是有點(diǎn) 貪婪思想
了,不到萬(wàn)不得已,都不會(huì)主動(dòng)斷開(kāi)連接。
流量控制
一條 TCP
連接每一側(cè)的主機(jī)都設(shè)置了緩沖區(qū)域,很多時(shí)候可能對(duì)于接收方來(lái)說(shuō)并不會(huì)立即去處理這些數(shù)據(jù),如果發(fā)送方一直發(fā)送數(shù)據(jù),就很可能導(dǎo)致接收方來(lái)不及處理,就像喂小孩子吃飯那樣,你一直給他塞飯,他根本咽不下是吧,所以 TCP
協(xié)議就提供了來(lái)了控制,消除發(fā)送方使接收方緩沖區(qū)溢出的可能,流量控制其實(shí)是一個(gè)速度匹配的服務(wù),讓接收方的處理速度趕得上發(fā)送方的發(fā)送速度,就像小孩子,吃飯的速度趕得上你喂食的速度,但是小孩子的自身(硬件)是沒(méi)法改變的,總不能讓他有我們的吃飯速度對(duì)不對(duì),那么只能改變我們喂食的速度了,我們慢一點(diǎn),小孩子就不會(huì)被噎著。
TCP
協(xié)議通過(guò)讓維護(hù)一個(gè)接收窗口的變量來(lái)提供流量控制,它是接收方用于給發(fā)送方一個(gè)指示:我還能接收多少數(shù)據(jù),接收方會(huì)將此窗口值放在 TCP
報(bào)文的首部中的窗口字段,然后通過(guò)確認(rèn)報(bào)文發(fā)送給發(fā)送方,這個(gè)窗口的值的大小是在發(fā)送數(shù)據(jù)的時(shí)候動(dòng)態(tài)調(diào)整的。
當(dāng)然,如果接收窗口的大小是 0
怎么辦?能想到這個(gè)問(wèn)題的人很牛逼, 留個(gè)言我給你點(diǎn)個(gè)贊
!
簡(jiǎn)單來(lái)說(shuō)說(shuō)協(xié)議棧通信的處理無(wú)非是兩種方式觸發(fā),要么是事件、要么是時(shí)間(定時(shí)器),事件觸發(fā)就是我在等你連接事件發(fā)生,然后我響應(yīng),時(shí)間觸發(fā)就是超時(shí)后我再處理,都是比較容易理解的。
回到如果接收窗口的大小是 0
怎么辦這個(gè)問(wèn)題,那么接收窗口為0時(shí),發(fā)送方應(yīng)該怎么發(fā)送數(shù)據(jù)呢,總不能不發(fā),也總不能是直接斷開(kāi)吧,既然這樣子,那應(yīng)該什么時(shí)候發(fā)呢?
當(dāng)發(fā)送方收到接收方的報(bào)文,報(bào)文中指定接收窗口的大小為0,那么這是一個(gè)事件,發(fā)送方就會(huì)啟動(dòng)一個(gè)探測(cè)定時(shí)器,來(lái)探測(cè)接收方什么時(shí)候能接收數(shù)據(jù),而定時(shí)器就可以產(chǎn)生超時(shí)對(duì)吧,每次超時(shí)就發(fā)送一個(gè)字節(jié)的數(shù)據(jù)給接收方,并且記錄超時(shí)的次數(shù)并且刷新定時(shí)器,如果在超時(shí)之前收到來(lái)自接收方的報(bào)文,報(bào)文中指定接收窗口的大小不為0,這也是一個(gè)事件,那么就關(guān)閉探測(cè)定時(shí)器,然后正常發(fā)送數(shù)據(jù)。當(dāng)然,如果超時(shí)次數(shù)到達(dá)極限,將終止 tcp
連接或者是 reset
。
擁塞控制
在局域網(wǎng)中傳輸數(shù)據(jù)的話,僅使用流量控制就能達(dá)到速度匹配的結(jié)果,這種理想情況還是非常好的,但是實(shí)際情況中,在發(fā)送方和接收方之間存在多個(gè)路由器和速率較慢的鏈路時(shí),就有可能出現(xiàn)一些問(wèn)題。一些中間路由器可能緩存IP數(shù)據(jù)報(bào),并有可能耗盡存儲(chǔ)器的空間,這就導(dǎo)致這些中間路由器不再接收IP數(shù)據(jù)報(bào)并轉(zhuǎn)發(fā),然后這些報(bào)文將被丟棄,而TCP協(xié)議發(fā)現(xiàn)被丟棄了又會(huì)重新發(fā)送,這種情況就導(dǎo)致越來(lái)越嚴(yán)重的問(wèn)題——擁塞。就像過(guò)年時(shí)候回家的大塞車。
TCP協(xié)議的發(fā)展,有越來(lái)越多的控制算法來(lái)避免這些問(wèn)題,比如慢啟動(dòng)算法,擁塞避免,擁塞發(fā)生,快速恢復(fù)等算法,慢啟動(dòng)為發(fā)送方的TCP增加了另一個(gè)窗口:擁塞窗口。當(dāng)與主機(jī)建立 TCP連接時(shí),擁塞窗口被初始化為 1個(gè)報(bào)文段(即另一端通告的報(bào)文段大小)。每收到一個(gè) ACK,擁塞窗口就增加一個(gè)報(bào)文段( 注意增加的不是字節(jié)而是報(bào)文段
)。
簡(jiǎn)單來(lái)說(shuō)就是:發(fā)送方開(kāi)始時(shí)發(fā)送一個(gè)報(bào)文段,然后等待 ACK
。當(dāng)收到該 ACK
時(shí),擁塞窗口從 1
增加為 2
,即可以發(fā)送兩個(gè)報(bào)文段。當(dāng)收到這兩個(gè)報(bào)文段的 ACK
時(shí),擁塞窗口就增加為 4
,這是一種指數(shù)增加的關(guān)系。
當(dāng)然啦,我這篇文章還是非常表面地介紹這些知識(shí),更多詳細(xì)知識(shí)還是得看書!
-
TCP
+關(guān)注
關(guān)注
8文章
1353瀏覽量
79055 -
傳輸數(shù)據(jù)
+關(guān)注
關(guān)注
1文章
122瀏覽量
16101 -
傳輸層協(xié)議
+關(guān)注
關(guān)注
0文章
6瀏覽量
1263
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論