TCP协议如何保证可靠传输
原文網址:TCP協議如何保證可靠傳輸_IT利刃出鞘的博客-CSDN博客
簡介
? ? ? ? 本文介紹TCP協議保證可靠傳輸的原理。
? ? ? ? 本內容也是Java后端面試常見的問題。
概述
TCP協議保證數據傳輸可靠性的方式主要有:
詳述
校驗和
????????計算方式:在數據傳輸的過程中,將發送的數據段都當做一個16位的整數。將這些整數加起來。并且前面的進位不能丟棄,補在后面,最后取反,得到校驗和。
- 發送方:在發送數據之前計算檢驗和,并進行校驗和的填充。
- 接收方:收到數據后,對數據以同樣的方式進行計算,求出校驗和,與發送方的進行比對。
?????????注意:如果接收方比對校驗和與發送方不一致,那么數據一定傳輸有誤。但是如果接收方比對校驗和與發送方一致,數據不一定傳輸成功。
確認應答與序列號
序列號
????????TCP傳輸時將每個字節的數據都進行了編號,這就是序列號。
????????序列號的作用不僅僅是應答的作用,有了序列號能夠將接收到的數據根據序列號排序,并且去掉重復序列號的數據。這也是TCP傳輸可靠性的保證之一。
確認應答
????????TCP傳輸的過程中,每次接收方收到數據后,都會對傳輸方進行確認應答。也就是發送ACK報文。這個ACK報文當中帶有對應的確認序列號,告訴發送方,接收到了哪些數據,下一次的數據從哪里發。
超時重傳
????????在進行TCP傳輸時,由于確認應答與序列號機制,也就是說發送方發送一部分數據后,都會等待接收方發送的ACK報文,并解析ACK報文,判斷數據是否傳輸成功。如果發送方發送完數據后,遲遲沒有等到接收方的ACK報文,這該怎么辦呢?而沒有收到ACK報文的原因可能是什么呢?
????????首先,發送方沒有介紹到響應的ACK報文原因可能有兩點:
????????TCP在解決這個問題的時候引入了一個新的機制,叫做超時重傳機制。簡單理解就是發送方在發送完數據后等待一個時間,時間到達沒有接收到ACK報文,那么對剛才發送的數據進行重新發送。如果是剛才第一個原因,接收方收到二次重發的數據后,便進行ACK應答。如果是第二個原因,接收方發現接收的數據已存在(判斷存在的根據就是序列號,所以上面說序列號還有去除重復數據的作用),那么直接丟棄,仍舊發送ACK應答。
????????那么發送方發送完畢后等待的時間是多少呢?如果這個等待的時間過長,那么會影響TCP傳輸的整體效率,如果等待時間過短,又會導致頻繁的發送重復的包。如何權衡?
????????由于TCP傳輸時保證能夠在任何環境下都有一個高性能的通信,因此這個最大超時時間(也就是等待的時間)是動態計算的。
????????在Linux中(BSD Unix和Windows下也是這樣)超時以500ms為一個單位進行控制,每次判定超時重發的超時時間都是500ms的整數倍。重發一次后,仍未響應,那么等待2*500ms的時間后,再次重傳。等待4*500ms的時間繼續重傳。以一個指數的形式增長。累計到一定的重傳次數,TCP就認為網絡或者對端出現異常,強制關閉連接。
連接管理
????????連接管理就是三次握手與四次揮手的過程,在前面詳細講過這個過程,這里不再贅述。保證可靠的連接,是保證可靠性的前提。
流量控制
????????接收端在接收到數據后,對其進行處理。如果發送端的發送速度太快,導致接收端的結束緩沖區很快的填充滿了。此時如果發送端仍舊發送數據,那么接下來發送的數據都會丟包,繼而導致丟包的一系列連鎖反應,超時重傳呀什么的。而TCP根據接收端對數據的處理能力,決定發送端的發送速度,這個機制就是流量控制。
????????在TCP協議的報頭信息當中,有一個16位字段的窗口大小。在介紹這個窗口大小時我們知道,窗口大小的內容實際上是接收端接收數據緩沖區的剩余大小。這個數字越大,證明接收端接收緩沖區的剩余空間越大,網絡的吞吐量越大。接收端會在確認應答發送ACK報文時,將自己的即時窗口大小填入,并跟隨ACK報文一起發送過去。而發送方根據ACK報文里的窗口大小的值的改變進而改變自己的發送速度。如果接收到窗口大小的值為0,那么發送方將停止發送數據。并定期的向接收端發送窗口探測數據段,讓接收端把窗口大小告訴發送端。
注:16位的窗口大小最大能表示65535個字節(64K),但是TCP的窗口大小最大并不是64K。在TCP首部中40個字節的選項中還包含了一個窗口擴大因子M,實際的窗口大小就是16為窗口字段的值左移M位。每移一位,擴大兩倍。?
擁塞控制
????????TCP傳輸的過程中,發送端開始發送數據的時候,如果剛開始就發送大量的數據,那么就可能造成一些問題。網絡可能在開始的時候就很擁堵,如果給網絡中在扔出大量數據,那么這個擁堵就會加劇。擁堵的加劇就會產生大量的丟包,就對大量的超時重傳,嚴重影響傳輸。
????????所以TCP引入了慢啟動的機制,在開始發送數據時,先發送少量的數據探路。探清當前的網絡狀態如何,再決定多大的速度進行傳輸。這時候就引入一個叫做擁塞窗口的概念。發送剛開始定義擁塞窗口為 1,每次收到ACK應答,擁塞窗口加 1。在發送數據之前,首先將擁塞窗口與接收端反饋的窗口大小比對,取較小的值作為實際發送的窗口。
????????擁塞窗口的增長是指數級別的。慢啟動的機制只是說明在開始的時候發送的少,發送的慢,但是增長的速度是非常快的。為了控制擁塞窗口的增長,不能使擁塞窗口單純的加倍,設置一個擁塞窗口的閾值,當擁塞窗口大小超過閾值時,不能再按照指數來增長,而是線性的增長。在慢啟動開始的時候,慢啟動的閾值等于窗口的最大值,一旦造成網絡擁塞,發生超時重傳時,慢啟動的閾值會為原來的一半(這里的原來指的是發生網絡擁塞時擁塞窗口的大小),同時擁塞窗口重置為 1。
慢開始
????????慢開始不是指cwnd的增長速度慢(指數增長),而是指TCP開始發送設置cwnd=1。
????????思路:不要一開始就發送大量的數據,先探測一下網絡的擁塞程度,也就是說由小到大逐漸增加擁塞窗口的大小。這里用報文段的個數的擁塞窗口大小舉例說明慢開始算法,實時擁塞窗口大小是以字節為單位的。如下圖:
為了防止cwnd增長過大引起網絡擁塞,設置一個慢開始門限(ssthresh狀態變量)
當cnwd<ssthresh,使用慢開始算法
當cnwd=ssthresh,既可使用慢開始算法,也可以使用擁塞避免算法
當cnwd>ssthresh,使用擁塞避免算法
擁塞避免(按線性規律增長)
????????擁塞避免并非完全能夠避免擁塞,是說在擁塞避免階段將擁塞窗口控制為按線性規律增長,使網絡比較不容易出現擁塞。
????????思路:讓擁塞窗口cwnd緩慢地增大,即每經過一個往返時間RTT就把發送方的擁塞控制窗口加一。
????????無論是在慢開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(其根據就是沒有收到確認,雖然沒有收到確認可能是其他原因的分組丟失,但是因為無法判定,所以都當做擁塞來處理),就把慢開始門限設置為出現擁塞時的發送窗口大小的一半。然后把擁塞窗口設置為1,執行慢開始算法。
加法增大與乘法減小
乘法減小:無論是慢開始階段還是擁塞避免,只要出現了網絡擁塞(超時),就把慢開始門限值ssthresh減半
加法增大:執行擁塞避免算法后,擁塞窗口線性緩慢增大,防止網絡過早出現擁塞
快重傳
????????快重傳要求接收方在收到一個失序的報文段后就立即發出重復確認(為的是使發送方及早知道有報文段沒有到達對方)而不要等到自己發送數據時捎帶確認。快重傳算法規定,發送方只要一連收到三個重復確認就應當立即重傳對方尚未收到的報文段,而不必繼續等待設置的重傳計時器時間到期。
????????由于不需要等待設置的重傳計時器到期,能盡早重傳未被確認的報文段,能提高整個網絡的吞吐量。
快恢復(與快重傳配合使用)
注意
發送方窗口的上限值=Min(接受窗口rwnd,擁塞窗口cwnd)
rwnd>cwnd 接收方的接收能力限制發送方窗口的最大值
rwnd<cwnd 網絡的擁塞限制發送方窗口的最大值
總結
以上是生活随笔為你收集整理的TCP协议如何保证可靠传输的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 集成电路中的工艺
- 下一篇: 进程的创建——fork函数