TCP相關問題解析

2021-09-23 13:16:52 字數 4401 閱讀 8105

首先來看看資料報的分片機制。

分段特指發生在使用tcp協議的傳輸層中的資料切分行為

分片特指發生在使用ipv4協議的網路ip層中的資料切分行為

ip分片在乙太網上,由於電氣限制,一幀不能超過1518位元組,除去乙太網幀頭14位元組(mac位址等)和幀尾4位元組校驗,還剩1500位元組,這個大小稱為mtu(最大傳輸單元)。 如果你的ip包大於1500位元組,ip層就會分片了。

分片重組是ip層乙個最重要的工作,其處理的主要思想:當資料報從乙個網路a進入另乙個網路b時,若原網路的資料報大於另乙個網路的最大資料報的長度,必須進行分片。因而在ip資料報的報頭有若干標識域註明分片包的共同標識號、分片的偏移量、是否最後一片及是否允許分片。傳輸途中的閘道器利用這些標識域進行分片,目有主機把收到的分片進行重組以恢重資料。

需要注意的,在分片的資料中,傳輸層的首部只會出現在第乙個分片中。因為傳輸層的資料格式對ip層是透明的,傳輸層的首部只有在傳輸層才會有它的作用,ip層不知道也不需要保證在每個分片中都有傳輸層首部。所以,在網路上傳輸的資料報是有可能沒有傳輸層首部的。

在網路程式設計中,我們要避免出現ip分片,原因是ip層是沒有超時重傳機制的,如果ip層對乙個資料報進行了分片,只要有乙個分片丟失了,只能依賴於傳輸層進行重傳,結果是所有的分片都要重傳一遍,這個代價有點大。由此可見,ip分片會大大降低傳輸層傳送資料的成功率,所以要避免ip分片。

對於udp包,我們需要在應用層去限制每個包的大小,一般不要超過1472位元組,即乙太網mtu(1500)—udp首部(8)—ip首部(20)。

對於tcp資料,應用層就不需要考慮這個問題,因為傳輸層已經幫我們做了。在建立連線的三次握手的過程中,連線雙方會相互通告mss(maximum segment size,最大報文段長度),mss一般是mtu—ip首部(20)—tcp首部(20),每次傳送的tcp資料都不會超過雙方mss的最小值,所以就保證了ip資料報不會超過mtu,避免了ip分片。

面向連線:是指通訊雙方在通訊時,要事先建立一條通訊線路,其有三個過程:建立連線、使用連線和釋放連線。**系統是乙個面向連線的模式,撥號、通話、掛機;tcp協議就是一種面向連線的協議。

面向無連線:是指通訊雙方不需要事先建立一條通訊線路,而是把每個帶有目的位址的包(報文分組)送到線路上,由系統自主選定路線進行傳輸。郵政系統是乙個無連線的模式,天羅地網式的選擇路線,天女散花式的傳播形式;ip、udp協議就是一種無連線協議。

1、兩端通訊之前必須建立一條通訊管道------->三次握手

2、通訊結束後,必須關閉通道,以釋放資源------->四次揮手

3、通訊過程中,要維護連線,兩端核心必須分配資源------->心跳包機制

4、【為什麼要建立這個連線】保證資料傳輸的可靠性

5、同步通訊雙方的tcp報文段的標識

注意:只有tcp有粘包現象,udp永遠不會粘包,因為tcp是基於資料流的協議,而udp是基於資料報的協議

傳送端可以是一k一k地傳送資料,而接收端的應用程式可以兩k兩k地提走資料,當然也有可能一次提走3k或6k資料,或者一次只提走幾個位元組的資料,也就是說,應用程式所看到的資料是乙個整體,或說是乙個流(stream),一條訊息有多少位元組對應用程式是不可見的,因此tcp協議是面向流的協議,這也是容易出現粘包問題的原因。而udp是面向訊息的協議,每個udp段都是一條訊息,應用程式必須以訊息為單位提取資料,不能一次提取任意位元組的資料,這一點和tcp是很不同的。

粘包問題主要還是因為接收方不知道訊息之間的界限,不知道一次性提取多少位元組的資料所造成的。

為什麼出現粘包現象

(1)傳送方原因:tcp缺省會使用nagle演算法。而nagle演算法主要做兩件事:1)只有上乙個分組得到確認,才會傳送下乙個分組;2)收集多個小分組,在乙個確認到來時一起傳送。所以,正是nagle演算法造成了傳送方有可能造成粘包現象。

(2)接收方原因:tcp接收到分組時,並不會立刻送至應用層處理,或者說,應用層並不一定會立即處理;實際上,tcp將收到的分組儲存至接收快取裡,然後應用程式主動從快取裡讀收到的分組。這樣一來,如果tcp接收分組的速度大於應用程式讀分組的速度,多個包就會被存至快取,應用程式讀時,就會讀到多個首尾相接粘到一起的包。

兩種情況下容易發生粘包問題:

傳送端需要等緩衝區滿才傳送出去,造成粘包(傳送資料時間間隔很短,資料了很小,會合到一起,產生粘包)

接收方不及時接收緩衝區的包,造成多個包接收(客戶端傳送了一段資料,服務端只收了一小部分,服務端下次再收的時候還是從緩衝區拿上次遺留的資料,產生粘包)

如何處理粘包現象

(1)傳送方:對於傳送方造成的粘包現象,我們可以通過關閉nagle演算法來解決,使用tcp_nodelay選項來關閉nagle演算法。

(2)接收方:遺憾的是tcp並沒有處理接收方粘包現象的機制,我們只能在應用層進行處理。

(3)應用層處理:應用層的處理簡單易行!並且不僅可以解決接收方造成的粘包問題,還能解決傳送方造成的粘包問題。

兩種途徑:

1)格式化資料:每條資料有固定的格式(開始符、結束符),這種方法簡單易行,但選擇開始符和結束符的時候一定要注意每條資料的內部一定不能出現開始符或結束符;

2)傳送長度:傳送每條資料的時候,將資料的長度一併傳送,比如可以選擇每條資料的前4位是資料的長度,應用層處理時可以根據長度來判斷每條資料的開始和結束。

什麼是心跳包機制??

所謂的心跳包就是(探測性的)資料報,之所以叫心跳包是因為:它像心跳一樣每隔固定時間發一次,以此來告訴伺服器,這個客戶端還活著。事實上這是為了保持長連線,至於這個包的內容,是沒有什麼特別規定的,不過一般都是很小的包,或者只包含包頭的乙個空包。

為什麼需要心跳包機制??

採用tcp連線的c/s模式軟體,連線的雙方在連線空閒狀態時,如果任意一方意外崩潰、宕機、網線斷開或路由器故障,另一方無法得知tcp連線已經失效,除非繼續在此連線上傳送資料導致錯誤返回。很多時候,這不是我們需要的。我們希望伺服器端和客戶端都能及時有效地檢測到連線失效,然後優雅地完成一些清理工作並把錯誤報告給使用者。

心跳檢測步驟:

1、客戶端每隔乙個時間間隔發生乙個探測包給伺服器,同時啟動乙個超時定時器 

2、伺服器端接收到檢測包,應該回應乙個包 

3、如果客戶端收到伺服器的應答包,則說明伺服器正常,停止超時定時器 

4、如果客戶端的超時定時器超時,依然沒有收到應答包,則說明伺服器掛了

不一定。若沒有設定超時時間以及使用心跳包機制,理論上是不會斷開的,但是在實際網路應用中,兩個主機之間的通訊往往需要穿越多個中間節點,例如路由器、閘道器、防火牆等。因此,兩個主機之間 tcp 連線的保持同樣會受到中間節點的影響。

在tcp中,tcp將每個位元組的資料都進行了編號,即為序列號(對每乙個資料的編號)

在第一次訊息傳送中,客戶端a隨機選取乙個序列號作為自己的初始序號傳送給服務端b;第二次訊息b使用ack對a的資料報進行確認,因為已經收到了序列號為x的資料報,準備接收序列號為x+1的包,所以ack=x+1,同時b告訴a自己的初始序列號,就是seq=y;第三條訊息a告訴b收到了b的確認訊息並準備建立連線,a自己此條訊息的序列號是x+1,所以seq=x+1,而ack=y+1是表示a正準備接收b序列號為y+1的資料報。

seq是資料報本身的序列號;ack是期望對方繼續傳送的那個資料報的序列號。

比如:當主機1給主機2傳送了1~1000這麼多資料時,主機2如果收到了就會給主機1應答(ack報文段,每乙個ack都帶有對應的確認序列號),表示你給我發的1~1000的資料我已經全部收到了(收到哪些資料),下次你再給我發就給我從1001資料開始發(下次從**開始發)。那麼主機1收到應答之後就知道對方已經收到了1~1000的全部資料,所以再一次傳送資料的時候他就會從1001開始發,後面都是依此類推的情況。

當然了,當主機1給主機2傳送了資料之後,經過一端時間主機1並沒有收到主機2的應答的情況也是有的,所以這個時候為了確保資料的準確到達,tcp就有了超時重傳機制。

第三次ack可以帶資料。第二次ack不可以帶資料:連線建立好了之後,誰傳送資料都可以

rfc793文件裡帶有syn標誌的過程包是不可以攜帶資料的,也就是說三次握手的前兩次是不可以攜帶資料的(邏輯上看,連線還沒建立,攜帶資料好像也有點說不過去)。重點就是第三次握手可不可以攜帶資料。

當a收到對方的零視窗通知時,就啟用該計時器,時間到則傳送乙個1位元組的探測報文,對方會在此時回應自身的接收視窗大小,如果結果仍未0,則重設持續計時器,繼續等待。

IntentFilter的相關問題解析

intentfilter是配合intent而生的,你有目標行動或者結果,那麼那些行動和結果就會有他完成的特定要求,這些要求就是intentfilter,可以理解為intent和intentfilter是相對應的。intent字面意思就是目標,目的。通俗一點,需要達成某些目標,則需要提供一些動作,這些...

高通LED相關問題解析

除錯gpio leds背光燈出現的問題。改版後,gpio控制三色燈 在進行msm8909專案的時候,在除錯gpio led背光燈的時候,出現了乙個要求,這個要求是需要對兩個gpio口同時進行初始化,並且能在同乙個dtsi的裝置節點裡以相同的label進行宣告,並能讓上層在對這兩個led背光燈進行同時...

程式開發字典樹相關問題解析

字典樹又稱字首樹或者trie樹,一種有序資料結構,用於儲存關聯陣列,鍵通常是字串。trie的核心思想是空間換時間。利用字串的公共字首來降低查詢時間的開銷以達到提高效率的目的。它的插入和查詢時間複雜度都為 o k 其中 k 為 key 的長度,與 trie 中儲存了多少個元素無關。trie 的缺點是空...