TCP可靠性的體現(xiàn):seq和ack機(jī)制

提到TCP和UDP的區(qū)別,很容易想到的就是TCP的可靠性,那TCP是通過什么機(jī)制實(shí)現(xiàn)了可靠性的呢?解釋這個(gè)之前先來區(qū)分TCP中的大寫ACK和小寫ack??匆粡埥?jīng)典的TCP三次握手過程圖:

TCP三次握手過程圖

這張圖里似乎有個(gè)大寫的ACK也有個(gè)小寫的ack,這也是容易混淆的地方。

大寫的ACK是控制位,在TCP報(bào)文頭中有8個(gè)標(biāo)志比特,也就是TCP報(bào)文頭中有8位大小的數(shù)據(jù)是標(biāo)志位,看一下TCP報(bào)文格式更好理解:

TCP報(bào)文

它們中的多個(gè)可以同時(shí)被設(shè)置成1:

CWR(Congestion Window Reduce):擁塞窗口減少標(biāo)志,用來表明它接收到了設(shè)置ECE標(biāo)志的TCP包。并且,發(fā)送方收到消息之后,通過減小發(fā)送窗口的大小來降低發(fā)送速率。

ECE(ECN Echo):用來在TCP三次握手時(shí)表明一個(gè)TCP端是具備ECN功能的。在數(shù)據(jù)傳輸過程中,它也用來表明接收到的TCP包的IP頭部的ECN被設(shè)置為 11,即網(wǎng)絡(luò)線路擁堵。

URG(Urgent):表示本報(bào)文段中發(fā)送的數(shù)據(jù)是否包含緊急數(shù)據(jù)。URG=1時(shí)表示有緊急數(shù)據(jù)。當(dāng)URG=1時(shí),后面的緊急指針字段才有效。

ACK:表示前面的確認(rèn)號字段是否有效。ACK=1時(shí)表示有效。只有當(dāng) ACK=1時(shí),前面的確認(rèn)號字段才有效。TCP規(guī)定,連接建立后,ACK必須為 1。

PSH(Push):告訴對方收到該報(bào)文段后是否立即把數(shù)據(jù)推送給上層。如果值為1,表示應(yīng)當(dāng)立即把數(shù)據(jù)提交給上層,而不是緩存起來。

RST:表示是否重置連接。如果RST=1,說明TCP連接出現(xiàn)了嚴(yán)重錯(cuò)誤(如主機(jī)崩潰),必須釋放連接,然后再重新建立連接。

SYN:在建立連接時(shí)使用,用來同步序號。當(dāng)SYN=1,ACK=0時(shí),表示這是一個(gè)請求建立連接的報(bào)文段;當(dāng)SYN=1,ACK=1時(shí),表示對方同意建立連接。SYN=1時(shí),說明這是一個(gè)請求建立連接或同意建立連接的報(bào)文。只有在前兩次握手中SYN才為1。

FIN:標(biāo)記數(shù)據(jù)是否發(fā)送完畢。如果 FIN=1,表示數(shù)據(jù)已經(jīng)發(fā)送完成,可以釋放連接。

這是大寫的ACK,而小寫的ack是確認(rèn)序列號,和它一對的是seq即順序序列號,也就是上圖TCP報(bào)文格式中的Sequence Number和Acknowledgment Number。

前面說了這么多只是為了區(qū)分TCP中的大寫ACK和小寫ack,也沒其他方法就用大小寫區(qū)分吧,本文關(guān)注的重點(diǎn)就是TCP中的seq和ack機(jī)制,通過它們實(shí)現(xiàn)了TCP的可靠性傳輸,當(dāng)然TCP通過很多方面去保證了可靠性傳輸,這里seq和ack機(jī)制是防止數(shù)據(jù)丟失丟包的機(jī)制。

順序號seq:用來標(biāo)識(shí)從TCP源端向TCP目的端發(fā)送的數(shù)據(jù)字節(jié)流,它表示在這個(gè)報(bào)文段中的第一個(gè)數(shù)據(jù)字節(jié)的順序號。理解起來就是TCP用順序號對每個(gè)字節(jié)進(jìn)行計(jì)數(shù)。由上圖TCP報(bào)文格式中可以看出序號是 32bit 的無符號數(shù),序號到達(dá) 后又重新開始計(jì)數(shù)。當(dāng)建立一個(gè)新的連接時(shí),順序號字段包含由這個(gè)主機(jī)選擇的該連接的初始順序號 ISN ( Initial Sequence Number ),也就是說seq并不一定是從0開始的,所以剛在畫TCP三次握手的時(shí)候,寫的seq=x,即使還沒有數(shù)據(jù)傳輸,seq包含了ISN后就成了一個(gè)隨機(jī)數(shù),并不是0。

確認(rèn)號ack:理解起來就一句話,所期望收到的下一個(gè)順序號seq。

TCP為應(yīng)用層提供全雙工服務(wù),這意味數(shù)據(jù)能在兩個(gè)方向上獨(dú)立地進(jìn)行傳輸,也就是說服務(wù)端和客戶端都可能成為數(shù)據(jù)接收或者數(shù)據(jù)發(fā)送的一端。

數(shù)據(jù)發(fā)送端在發(fā)送TCP報(bào)文時(shí),計(jì)算在本次seq計(jì)數(shù)內(nèi),之前所有發(fā)送的報(bào)文中數(shù)據(jù)長度之和是多少,也就是計(jì)數(shù)記到哪里了,這就是seq。然后再計(jì)算之前所有收到的報(bào)文中收到的數(shù)據(jù)長度之和是多少,這就是ack。需要注意的是seq和ack是分開計(jì)數(shù)的。需要注意的是,SYN和FIN的TCP報(bào)文傳輸雖然沒有數(shù)據(jù),但是數(shù)據(jù)長度算1,ACK的傳輸,數(shù)據(jù)長度算0。

數(shù)據(jù)接收端收到TCP報(bào)文后,將這次報(bào)文中的seq取出來,和自己最后一次發(fā)送的ack對比,如果一致,則代表數(shù)據(jù)沒有丟失,理解起來就是這次的順序號和上次自己期望的順序號一致嘛。如果不一致就說明有丟包發(fā)生。其實(shí)就是TCP用0~對每個(gè)字節(jié)進(jìn)行計(jì)數(shù),用下圖舉個(gè)例子解釋一下:

示例圖

三個(gè)過程:

1.A在發(fā)送某個(gè)TCP報(bào)文前,發(fā)現(xiàn)此時(shí)自己這邊的seq計(jì)數(shù)已經(jīng)到了x,那這次的報(bào)文中seq=x,也就是在一次seq計(jì)數(shù)內(nèi),該端之前所有發(fā)送的報(bào)文中數(shù)據(jù)長度之和為x。然后這次又在這個(gè)報(bào)文中攜帶了長度為100bit的數(shù)據(jù)。

2.B在收到這個(gè)報(bào)文后,拿到報(bào)文中的seq=x,又拿到了長度為100bit的數(shù)據(jù),然后回包的時(shí)候ack=x+100。意思是告訴B你已經(jīng)發(fā)了x+100位的數(shù)據(jù)了,下次發(fā)包的時(shí)候別忘了把seq改成x+100。

3.A收到B回的數(shù)據(jù)包后,拿到報(bào)文中的ack=x+100,然后和自己這邊的計(jì)數(shù)著的seq一比對,如果一樣,說明A發(fā)的B都收到了沒問題,如果不一樣,假如A一看自己這邊的seq已經(jīng)等于y了,也就是自己計(jì)數(shù)著的已經(jīng)發(fā)送y位的數(shù)據(jù)了,可是聽B的意思它才收到x+100位數(shù)據(jù),丟包了唄。然后就是重發(fā)什么的是TCP的另外一些機(jī)制。

TCP就是通過seq和ack機(jī)制去確認(rèn)傳輸過程中有沒有丟包現(xiàn)象,前面說在一次計(jì)數(shù)范圍內(nèi),seq并不一定是從0開始的,可以當(dāng)我們用Wireshark抓包時(shí),上面顯示的seq確實(shí)從0開始的,這是因?yàn)閃ireshark等抓包軟件為了讓seq和ack展示更直觀,自動(dòng)幫我們減去了初始順序號 ISN,當(dāng)然也可以設(shè)置為直接展示真正的seq和ack,那就看著比較亂了,貼一張Wireshark處理后的seq和ack變化過程圖:

seq和ack變化過程圖

圖中前三步即TCP的三次握手,之后是數(shù)據(jù)傳輸??梢越Y(jié)合該圖去更好的理解本文。

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

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

  • seq和ack號存在于TCP報(bào)文段的首部中,seq是序號,ack是確認(rèn)號,大小均為4字節(jié)(注意與大寫的ACK不同,...
    JL_chen閱讀 4,553評論 1 1
  • 讀懂了TCP/IP協(xié)議,也就基本了解的網(wǎng)絡(luò)通信原理。本文是參照研究生教材《網(wǎng)絡(luò)安全原理與應(yīng)用》里面的內(nèi)容加上自己實(shí)...
    Super超人閱讀 22,673評論 1 19
  • TCP數(shù)據(jù)報(bào)首部格式 建立連接——三次握手 TCP/IP協(xié)議中,TCP協(xié)議提供可靠的連接服務(wù),采用三次握手建立一個(gè)...
    妖云小離閱讀 271評論 0 1
  • TCP協(xié)議精講 轉(zhuǎn)發(fā)自 https://mp.weixin.qq.com/s/5-Mt-IScPJ6KXTwIX_...
    o0O0o_b39d閱讀 1,009評論 0 0
  • 上篇分析了LengthFieldBasedFrameDecoder,只需要簡單靈活的指定幾個(gè)參數(shù)就能滿足多種情況下...
    李亞林1990閱讀 871評論 0 3

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