傳輸控制協(xié)議TCP

在網(wǎng)絡(luò)傳輸中,傳輸控制協(xié)議(TCP)是傳輸層非常重要的一個(gè)協(xié)議,所以學(xué)習(xí)TCP協(xié)議是很有必要的一件事情。TCP協(xié)議是一種可靠的、一對(duì)一的、面向有連接的一種通信協(xié)議,通常在TCP的網(wǎng)絡(luò)請(qǐng)求中,在獲取到對(duì)應(yīng)的IP地址后,會(huì)以隨機(jī)端口(1024-65535)向服務(wù)器80端口發(fā)起TCP的連接請(qǐng)求,這個(gè)連接會(huì)經(jīng)過TCP/IP協(xié)議棧,最后到達(dá)服務(wù)器。而在建立連接這個(gè)過程中,通過一次三次握手來確定連接的建立。

首先,明確一點(diǎn),因?yàn)榉?wù)器端維護(hù)的只是一個(gè)端口,并沒有主動(dòng)建立連接的能力,所以只有客戶端能主動(dòng)的建立與服務(wù)器端的連接,所以TCP請(qǐng)求的發(fā)起者一定是為客戶端。這里先來看一張圖。

三次握手

我們知道發(fā)起連接的一定是客戶端,那來看看三次握手的詳細(xì)過程。

第一次握手:客戶端發(fā)送SYN報(bào)文到服務(wù)器,服務(wù)器收到SYN報(bào)文之后能確定什么信息呢?信息1->,客戶端發(fā)送能力是正常,信息2->服務(wù)器端明確自己的接收能力是正常。(服務(wù)器端明確的信息)

第二次握手:服務(wù)器端回應(yīng)客戶端的信息,將收到SYN報(bào)文中的seq數(shù)據(jù)加一,將其作為創(chuàng)建的ACK的數(shù)據(jù),再設(shè)置一個(gè)新的Seq數(shù)據(jù),將這個(gè)ACK和SYN的報(bào)文發(fā)送回客戶端。在客戶端收到SYN和ACK報(bào)文之后。會(huì)得到的信息為,信息1->服務(wù)器端的接收能力正常,信息2->服務(wù)器端的發(fā)送能力正常,信息3->客戶端的接收能力正常。(客戶端明確的信息)

第三次握手:客戶端回應(yīng)服務(wù)器端的信息,將收到服務(wù)器SYN信息中的Seq數(shù)據(jù)加一,將其作為新的ACK的數(shù)據(jù)。發(fā)送給服務(wù)器端,服務(wù)器收到ACK信息之后,會(huì)確定的信息。信息1->客戶端的接收和發(fā)送能力正常。信息2->服務(wù)器端的接收和發(fā)送能力正常。(服務(wù)器端明確的信息)

經(jīng)過三次握手之后,建立起雙方之間的連接,三次握手主要的作用是來確定客戶端和服務(wù)器端的發(fā)送和接收能力都正常之后才能建立連接。這里其實(shí)會(huì)有疑問,一次,兩次,四次不可以嘛?根據(jù)作用來說,一次和兩次肯定是不能完全讓客戶端和服務(wù)器端來明確對(duì)方的所有的狀態(tài)信息。而四次的話,又會(huì)造成不必要的資源浪費(fèi),所以三次是最簡(jiǎn)潔明了的,確保兩端都獲取到對(duì)方狀態(tài)信息。

圖片文字只是理論,我們還是需要實(shí)際的行動(dòng)來驗(yàn)證理論,這里來看下使用Wiresshark抓包工具獲取到的信息。

在這里呢,使用nc命令在終端來模擬客戶端連接服務(wù)器,nc -l 6060的為,打開一個(gè)6060的端口。nc 127.0.0.1(IP地址)6060(端口)連接6060端口。左邊的終端可以視作服務(wù)器,右邊的終端視作客戶端。

在抓包工具中這里可以看到四次?不是三次握手嘛?不要著急,看到第四次的信息是TCP窗口更新,所以這個(gè)明確的知道這不是TCP協(xié)議中的握手。

這里看到的是三次的握手,這里主要關(guān)注的幾個(gè)點(diǎn)

SYN:報(bào)文段,不能攜帶數(shù)據(jù)(發(fā)起建立報(bào)文,會(huì)消耗一個(gè)序列號(hào))

Seq:全稱為sequence number,序列號(hào)(第一次隨機(jī)產(chǎn)生,后續(xù)報(bào)文中累加)很重要

ACK:報(bào)文段,可以攜帶數(shù)據(jù)(確認(rèn)報(bào)文,如果攜帶數(shù)據(jù),則會(huì)消耗一個(gè)序列號(hào),如果不攜帶數(shù)據(jù),則不會(huì)消耗序列號(hào)seq)

Ack:是ACK的序列號(hào),根據(jù)SYN報(bào)文中的Seq來生成

第一次握手:[SYN] 為報(bào)文段的類型,可以看到在1中的報(bào)文中的Seq為2812367146,這是一個(gè)隨機(jī)產(chǎn)生的序列號(hào),每一次的報(bào)文都會(huì)有自己的序列號(hào)作為標(biāo)識(shí)。服務(wù)器端接收到這個(gè)SYN報(bào)文之后,知道的信息為,客戶端發(fā)送了一個(gè)建立連接的SYN包,編號(hào)為2812376146。

第二次握手:在2中有兩個(gè)報(bào)文段是[SYN,ACK],SYN報(bào)文的序列號(hào)seq為一個(gè)新隨機(jī)產(chǎn)生的序列號(hào)587195924,而新創(chuàng)建的ACK報(bào)文的Ack序列號(hào)為2812367147。這里的意思是服務(wù)器端發(fā)出的意思是為兩重,第一個(gè)是建立連接的SYN信息,有自己生成的seq。第二個(gè)是確認(rèn)的ACK信息,將第一次握手收到的SYN信息中的Seq+1作為ACK的序列號(hào),告訴客戶端,收到了2812376146這個(gè)序列號(hào)的SYN報(bào)文。

第三次握手:在3中只有一個(gè)ACK的報(bào)文,ACK的Ack序號(hào)為587195925。這里的意思是確認(rèn)了服務(wù)器的SYN包,Ack的序號(hào)為第二次握手中SYN包中Seq+1,因?yàn)檫@里的ACK報(bào)文只是確認(rèn),并沒有攜帶數(shù)據(jù),所以這里的seq還是第二次握手中ACK的序號(hào)。

通過三次握手的連接之后,下一次報(bào)文中的Seq序列號(hào)為第三次ACK報(bào)文中Seq+1

四次揮手

抓包工具的數(shù)據(jù)也驗(yàn)證了理論,所以接下來我們來看一下斷開連接的四次揮手,同樣從理論到驗(yàn)證,如下圖所示

圖中第一次揮手實(shí)際應(yīng)為FIN和ACK

問題:四次揮手一定是客戶端發(fā)起嘛?

答案:這是不一定的,因?yàn)樵赥CP的連接中,所以只要有任何一端發(fā)起了斷開的請(qǐng)求,對(duì)方收到響應(yīng)之后做出斷開請(qǐng)求的四次揮手,即完成了斷開連接。所以斷開連接的四次揮手可以為客戶端發(fā)起,同樣也可以由服務(wù)器端發(fā)起。

上圖中為客戶端發(fā)起斷開連接的步驟,服務(wù)器端發(fā)起是同樣的道理。

第一次揮手:客戶端發(fā)送一個(gè)FIN和ACK的報(bào)文,序列號(hào)seq為傳輸數(shù)據(jù)包中最后一次的Seq+1,ACK的序列號(hào)Ack則為上一次ACK包中的序列號(hào)。將客戶端的狀態(tài)修改為FIN_WAIT1。服務(wù)器收到之后明確信息->客戶端在等待關(guān)閉。

第二次揮手:服務(wù)器將收到FIN報(bào)文中的Seq數(shù)據(jù)+1作為新ACK報(bào)文的Ack,將收到的ACK報(bào)文中的Ack+1作為新報(bào)文ACK的Seq,將服務(wù)器端的狀態(tài)調(diào)整為CLOSE_WAIT,然后將新的確認(rèn)報(bào)文ACK發(fā)送給客戶端。客戶端收到之后明確信息->服務(wù)器端知曉客戶端在等待關(guān)閉,同時(shí)將客戶端的狀態(tài)調(diào)整為FIN_WAIT2。

第三次揮手:服務(wù)器再次的發(fā)起FIN和ACK的報(bào)文,F(xiàn)IN的Seq是最后一次報(bào)文的Seq+1,ACK報(bào)文的Ack是最后一次ACK報(bào)文的的Ack+1,將服務(wù)器端的狀態(tài)修改為L(zhǎng)AST_ACK。客戶端在收到之后明確信息->服務(wù)器端發(fā)送了最后一次,在等待關(guān)閉。

第四次揮手:客戶端發(fā)起ACK報(bào)文,新的ACK報(bào)文的seq為第三次揮手收到的Ack,而Ack為收到FIN中的Seq+1,將自己的狀態(tài)調(diào)整為TIME_WAIT。服務(wù)器端收到之后明確信息->客戶端關(guān)閉,將服務(wù)器端的狀態(tài)調(diào)整為CLOSED。而客戶端在TIME_WAIT狀態(tài)等待2MSL秒之后,將自己的狀態(tài)調(diào)整為CLOSED。

同樣這里使用抓包工具來驗(yàn)證

這里的數(shù)據(jù)就不一一解讀了,因?yàn)樵谶B接之后,沒有做任何的數(shù)據(jù)傳輸,所以這里的Seq和Ack的序號(hào)和連接的時(shí)候是連續(xù)的。

FIN:報(bào)文段,不能攜帶數(shù)據(jù)(關(guān)閉報(bào)文,會(huì)消耗一個(gè)序列號(hào))

這里說明一下兩個(gè)點(diǎn)

1:為什么一定要四次揮手,可以看到,在關(guān)閉的時(shí)候,第二次和第三次揮手都是由被動(dòng)方(圖中為服務(wù)器端)發(fā)起,因?yàn)樵谀承r(shí)候可能傳輸?shù)膱?bào)文還沒有傳輸完成,所以先通知客戶端收到關(guān)閉的請(qǐng)求,然后確認(rèn)服務(wù)器端的傳輸都完成之后,再發(fā)起第三次揮手,告訴客戶端要斷開連接。

2:為什么在最后一次揮手之后要等待2MSL再調(diào)整狀態(tài)為CLOSED,兩個(gè)原因,第一,是需要確定已經(jīng)發(fā)出去,因?yàn)锳CK報(bào)文有可能丟失,會(huì)需要重發(fā)。第二,如果立馬關(guān)閉的話,有可能在下一次連接的是相同的IP和端口,為了防止舊連接和新連接的數(shù)據(jù)發(fā)生混亂,所以設(shè)置等待的時(shí)間讓舊連接的數(shù)據(jù)完全關(guān)閉,這樣就不會(huì)讓舊連接和新連接之間數(shù)據(jù)造成混亂。

保障數(shù)據(jù)包有效

TCP是可靠的數(shù)據(jù)連接,可是只是通過三次握手和四次揮手就一定能保證數(shù)據(jù)的傳輸不會(huì)出現(xiàn)問題嘛?當(dāng)然是不可以,所以TCP通過以下的幾個(gè)控制來確保數(shù)據(jù)包的傳輸有效。

一,校驗(yàn)和

1、首先將檢驗(yàn)和置零;

2、然后將TCP偽首部部分,TCP首部部分,數(shù)據(jù)部分都劃分成16位的一個(gè)個(gè)16進(jìn)制數(shù)

3、將這些數(shù)逐個(gè)相加,記得溢出的部分加到最低位上,這是循環(huán)加法:0xc0a8+ 0x0166+……+0x0402=0x9b49

4、最后將得到的結(jié)果取反,則可以得到檢驗(yàn)和位0x64b6

發(fā)送方:原碼相加 ,并將高位疊加到低位,取反 ,得到反碼求和結(jié)果,放入校驗(yàn)和

接收方:將所有原碼 相加,高位疊加, 如全為1,則正確

發(fā)送的數(shù)據(jù)包的二進(jìn)制相加然后取反,目的是檢測(cè)數(shù)據(jù)在傳輸過程中的任何變化。如果收到報(bào)文段的檢驗(yàn)和有差錯(cuò),TCP將丟棄這個(gè)報(bào)文段和不確認(rèn)收到此報(bào)文段,這時(shí) TCP 發(fā)送數(shù)據(jù)端超時(shí)后會(huì)重發(fā)數(shù)據(jù);

二. 確認(rèn)應(yīng)答+序列號(hào)

序列號(hào):TCP傳輸時(shí)將每個(gè)字節(jié)的數(shù)據(jù)都進(jìn)行了編號(hào),這就是序列號(hào)Seq。

確認(rèn)應(yīng)答:TCP傳輸?shù)倪^程中,每次接收方收到數(shù)據(jù)后,都會(huì)對(duì)傳輸方進(jìn)行確認(rèn)應(yīng)答,也就是發(fā)送ACK報(bào)文。這個(gè)ACK報(bào)文當(dāng)中帶有對(duì)應(yīng)的確認(rèn)序列號(hào),告訴發(fā)送方,接收到了哪些數(shù)據(jù),下一次的數(shù)據(jù)從哪里發(fā)。

序列號(hào)的作用不僅僅是應(yīng)答的作用,有了序列號(hào)能夠?qū)⒔邮盏降臄?shù)據(jù)根據(jù)序列號(hào)排序,并且去掉重復(fù)序列號(hào)的數(shù)據(jù)。

應(yīng)答機(jī)制:當(dāng) TCP 收到發(fā)自 TCP 連接另一端的數(shù)據(jù),它將發(fā)送一個(gè)確認(rèn)(累積確認(rèn):對(duì)所有按序接收的數(shù)據(jù)的確認(rèn))。這個(gè)確認(rèn)不是立即發(fā)送,通常將推遲幾分之一秒

TCP給發(fā)送的每一個(gè)包進(jìn)行編號(hào),接收方對(duì)數(shù)據(jù)包進(jìn)行排序,把有序數(shù)據(jù)傳送給應(yīng)用層。

三,超時(shí)重傳

當(dāng)報(bào)文發(fā)出后在一定的時(shí)間內(nèi)未收到接收方的確認(rèn),發(fā)送方就會(huì)進(jìn)行重傳(通常是在發(fā)出報(bào)文段后設(shè)定一個(gè)鬧鐘,到點(diǎn)了還沒有收到應(yīng)答則進(jìn)行重傳)

接收方獲取到重復(fù)的數(shù)據(jù)之后,利用序列號(hào)識(shí)別到重復(fù)的數(shù)據(jù),將其丟棄,再重新發(fā)送ack報(bào)文

四,流量控制

TCP根據(jù)接收端的處理能力,決定發(fā)送端的發(fā)送速度,TCP通過滑動(dòng)窗口來進(jìn)行流量控制

流量窗口:因?yàn)門CP是全雙工通信,通信的任意一方都會(huì)維護(hù)另一方的接收窗口(即接收方當(dāng)前可用的緩存空間),數(shù)據(jù)是動(dòng)態(tài)變化的,緩存空間也是動(dòng)態(tài)的,也稱之為滑動(dòng)窗口

五,擁塞控制

為了避免由于網(wǎng)絡(luò)擁堵而采取的對(duì)發(fā)送方發(fā)送速率的限制稱為擁塞控制

TCP 通過擁塞窗口實(shí)現(xiàn)擁塞避免->TCP 的每一端除了維護(hù)進(jìn)行流量控制的滑動(dòng)窗口外,還會(huì)維護(hù)一個(gè)擁塞窗口(cwnd),擁塞窗口就是對(duì) TCP 發(fā)送方的發(fā)送速率進(jìn)行限制的,具體來說的就是 TCP 會(huì)控制發(fā)送方發(fā)送到連接中的但是還沒有被接收方確認(rèn)的數(shù)據(jù)量。

通過上述的控制,這樣就給數(shù)據(jù)的傳輸安全有了一定的保障。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 傳輸控制協(xié)議是啥? 傳輸控制協(xié)議其實(shí)就是我們嘴上老是說的TCP,但是以前壓根就沒了解過,也就是跟著別人說而已。上了...
    LU7IN閱讀 1,548評(píng)論 0 3
  • 1. 簡(jiǎn)介 TCP提供一種可靠的面向連接的全雙工服務(wù),位于傳輸層。 2. TCP報(bào)文段結(jié)構(gòu) TCP報(bào)文段包括首部字...
    謝樸歡閱讀 309評(píng)論 0 1
  • 12.1 引言 UDP協(xié)議能夠檢測(cè)接收到的數(shù)據(jù)是否有差錯(cuò),但是不能糾正糾正的意思是恢復(fù)接受道德錯(cuò)誤數(shù)據(jù),第二就是...
    Myth52125閱讀 650評(píng)論 0 0
  • TCP/IP傳輸協(xié)議 TCP/IP是指能夠在多個(gè)不同網(wǎng)絡(luò)間實(shí)現(xiàn)信息傳輸?shù)膮f(xié)議簇。TCP/IP協(xié)議不僅僅指的是TCP...
    Snipers_onk閱讀 485評(píng)論 0 0
  • 一、TCP的可靠性 TCP向應(yīng)用層提供與UDP完全不同的服務(wù)。它提供一種面向連接的、可靠的字節(jié)流服務(wù)。TCP通過下...
    ZMRWEGo閱讀 1,429評(píng)論 0 0

友情鏈接更多精彩內(nèi)容