TCP的可靠性

說起TCP協(xié)議,可能這句話很多人都聽過,那就是TCP的定義:

TCP(Transmission Control Protocol 傳輸控制協(xié)議)是一種面向連接(連接導(dǎo)向)的、可靠的、 基于IP的傳輸層協(xié)議。

面向連接這個很好理解,TCP協(xié)議要求數(shù)據(jù)傳輸之前建立連接,數(shù)據(jù)傳輸完成后將連接拆除。TCP是基于IP的的傳輸層協(xié)議,這個也沒什么好說的,看一下TCP IP網(wǎng)絡(luò)模型就能明白。今天主要談?wù)摰木褪荰CP的可靠性,也就是咱們?yōu)槭裁磳CP看成一個可靠的傳輸層協(xié)議,它的可靠性又從何而來。

首先咱們看一下TCP的報頭有哪些字段,其含義是什么。


TCP報頭格式.jpeg

16位端口號(port number):告知主機該報文段是來自哪里(源端口)以及傳給哪個上層協(xié)議或應(yīng)用程序(目的端口)的。進(jìn)行TCP通信時,客戶端通常使用系統(tǒng)自動選擇的臨時端口號,而服務(wù)器則使用知名服務(wù)端口號。

32位序號(sequence number):一次TCP通信(從TCP連接建立到斷開)過程中某一個傳輸方向上的字節(jié)流的每個字節(jié)的編號。假設(shè)主機A和主機B進(jìn)行TCP通信,A發(fā)送給B的第一個TCP報文段中,序號值被系統(tǒng)初始化為某個隨機值ISN(Initial Sequence Number,初始序號值)。那么在該傳輸方向上(從A到B),后續(xù)的TCP報文段中序號值將被系統(tǒng)設(shè)置成ISN加上該報文段所攜帶數(shù)據(jù)的第一個字節(jié)在整個字節(jié)流中的偏移。

32位確認(rèn)號(acknowledgement number):用作對另一方發(fā)送來的TCP報文段的響應(yīng)。其值是收到的TCP報文段的序號值加1。假設(shè)主機A和主機B進(jìn)行TCP通信,那么A發(fā)送出的TCP報文段不僅攜帶自己的序號,而且包含對B發(fā)送來的TCP報文段的確認(rèn)號。反之,B發(fā)送出的TCP報文段也同時攜帶自己的序號和對A發(fā)送來的報文段的確認(rèn)號。

4位頭部長度(header length):標(biāo)識該TCP頭部有多少個32bit字(4字節(jié))。因為4位最大能表示15,所以TCP頭部最長是60字節(jié)。

6位標(biāo)志位包含如下幾項:

URG標(biāo)志,表示緊急指針(urgent pointer)是否有效。

ACK標(biāo)志,表示確認(rèn)號是否有效。我們稱攜帶ACK標(biāo)志的TCP報文段為確認(rèn)報文段。

PSH標(biāo)志,提示接收端應(yīng)用程序應(yīng)該立即從TCP接收緩沖區(qū)中讀走數(shù)據(jù),為接收后續(xù)數(shù)據(jù)騰出空間。

RST標(biāo)志,表示要求對方重新建立連接。我們稱攜帶RST標(biāo)志的TCP報文段為復(fù)位報文段。

SYN標(biāo)志,表示請求建立一個連接。我們稱攜帶SYN標(biāo)志的TCP報文段為同步報文段。

FIN標(biāo)志,表示通知對方本端要關(guān)閉連接了。我們稱攜帶FIN標(biāo)志的TCP報文段為結(jié)束報文段。

16位窗口大小(window size):是TCP流量控制的一個手段。這里說的窗口,指的是接收通告窗口(Receiver Window,RWND)。它告訴對方本端的TCP接收緩沖區(qū)還能容納多少字節(jié)的數(shù)據(jù),這樣對方就可以控制發(fā)送數(shù)據(jù)的速度。

16位校驗和(TCP checksum):由發(fā)送端填充,接收端對TCP報文段執(zhí)行CRC算法以檢驗TCP報文段在傳輸過程中是否損壞。注意,這個校驗不僅包括TCP頭部,也包括數(shù)據(jù)部分。這也是TCP可靠傳輸?shù)囊粋€重要保障。

16位緊急指針(urgent pointer):是一個正的偏移量。它和序號字段的值相加表示最后一個緊急數(shù)據(jù)的下一字節(jié)的序號。TCP的緊急指針是發(fā)送端向接收端發(fā)送緊急數(shù)據(jù)的方法

在TCP報頭中,與可靠性相關(guān)的字段有很多,所以當(dāng)一個應(yīng)用程序把數(shù)據(jù)流交付給TCP后,TCP有天然的優(yōu)勢保證將這些數(shù)據(jù)以按序的、沒有差錯的、也沒有任何一部分丟失或重復(fù)的狀態(tài)交付另外一端的應(yīng)用程序。

如何做到的?

  • 每個TCP報文段都有一個校驗和字段。TCP規(guī)定每個報文段都必須使用16位的校驗和,且如果某個報文段因校驗和無效而被檢查出受到損傷,就由終點TCP將其丟失,并被認(rèn)為是丟失了。

  • 每個TCP報文段都有一個確認(rèn)號字段,用來實現(xiàn)對收到的報文段進(jìn)行確認(rèn),并宣稱下次期望接收的下一個字節(jié)的序號是什么。只有當(dāng)A端收到來自B端的確認(rèn)報文段后,A端才會認(rèn)定之前發(fā)送的數(shù)據(jù)安全到達(dá),并發(fā)送下一段數(shù)據(jù)(某些情況下不是這樣)。相當(dāng)于對快遞的簽收吧。

  • 發(fā)送方TCP會為每一條連接設(shè)置一個重傳超時計時器(RTO)。在一個報文段發(fā)送是,它會被保存到一個隊列中,知道被確認(rèn)為止。當(dāng)重傳計時器超時,或者發(fā)送方收到該隊列中第一個報文段的三個重復(fù)ACK時(快重傳機制),該報文段被重傳。TCP中重傳計時器的值是動態(tài)的,它根據(jù)報文段的往返時間(RTT)更新,一個RTT是一個報文段到底終點并受到它的確認(rèn)所需的時間。

通過以上三點,我們可以得知:

TCP通過校驗和、確認(rèn)以及超時重傳這三個工具,來檢測和重傳受到損傷的報文段、并重傳丟失的報文段、保存失序到底的報文段直至缺失的報文段到期,以及檢測和丟棄重復(fù)的報文段。我們經(jīng)常將TCP的這個特性稱之為『差錯控制』。

  • 每個TCP報文段都有一個窗口大小字段,TCP為每個方向的數(shù)據(jù)傳送各使用兩個窗口(發(fā)送窗口和接收窗口)。接收窗口大小決定了接收窗口在溢出之前能夠接收的字節(jié)數(shù),接收窗口總是小于或等于緩存的大小。接收方可以向發(fā)送方反饋自己的窗口大小,也就是是自己能夠接收的最大字節(jié)數(shù),發(fā)送方會動態(tài)的調(diào)整自己的發(fā)送窗口,從而避免發(fā)送方發(fā)送過多的數(shù)據(jù)導(dǎo)致接收方無法及時接受,從而溢出。

通過第四點,我們可以得知:

TCP通過接收窗口的大小來調(diào)節(jié)生產(chǎn)者產(chǎn)生數(shù)據(jù)的速度和消費者消耗數(shù)據(jù)的數(shù)據(jù),達(dá)到一種動態(tài)平衡。我們經(jīng)常將TCP的這個特性稱之為『流量控制』。

  • 除了接收窗口會影響到發(fā)送方的窗口大小外,網(wǎng)絡(luò)也是一個非常重要的影響因素。如果網(wǎng)絡(luò)不能像發(fā)送方產(chǎn)生數(shù)據(jù)那樣快的把數(shù)據(jù)交付給接收發(fā),那么它就必須通知發(fā)送方網(wǎng)絡(luò)有擁塞,需要調(diào)整發(fā)送窗口大小,放慢數(shù)據(jù)的發(fā)送速度。TCP處理擁塞的一般策略是基于三個階段:
    1、慢開始(指數(shù)增大)
    2、擁塞避免(加法增大)
    3、擁塞檢測(乘法減?。?br> 在慢開始階段,發(fā)送方從非常慢的傳輸速率開始發(fā)送數(shù)據(jù),但很快就把速率增大到一個門限值。當(dāng)?shù)竭_(dá)門限值后,速率增長開始放慢,直到檢測到擁塞后發(fā)送方便回到慢開始或者是擁塞避免階段。這兒我們將數(shù)據(jù)的傳輸速率稱之為擁塞窗口。
真正的發(fā)送窗口大小 = min(接收窗口大小、擁塞窗口大?。?/h6>

通過第五點,我們可以得知:

TCP使用了一個擁塞窗口和一個擁塞策略來避免擁塞,并在擁塞發(fā)生后檢測和緩解擁塞。我們經(jīng)常將TCP的這個特性稱之為『擁塞控制』。


總結(jié)一下,TCP的有三個重要的特性,差錯控制、流量控制和擁塞控制,正是因為這三個特性,我們將TCP視為一個可靠的傳輸層協(xié)議。

夜深了,睡覺去。如有錯誤,還望指正。

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

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

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