TCP頭部分析與確認號的理解


1、TCP的特點:

基於字節流
面向連接
可靠傳輸
緩沖傳輸
全雙工
流量控制

 

2、頭部格式和說明

圖源百度。如下圖示,就是TCP包的頭部結構。可以看到這個頭部最少有4x5=20個字節。

另外還需要理解TCP協議是承載在IP協議中的。關於IP協議可以參考:http://www.cnblogs.com/xcywt/p/8067521.html

源端口號和目的端口號:再加上Ip首部的源IP地址和目的IP地址可以唯一確定一個TCP連接
數據序號:表示在這個報文段中的第一個數據字節序號
確認序號:僅當ACK標志為1時有效。確認號表示期望收到的下一個字節的序號(這個下面再詳細分析)
偏移:就是頭部長度,有4位,跟IP頭部一樣,以4字節為單位。最大是60個字節
保留位:6位,必須為0
6個標志位:
URG-緊急指針有效
ACK-確認序號有效
PSH-接收方應盡快將這個報文交給應用層
RST-連接重置
SYN-同步序號用來發起一個連接
FIN-終止一個連接

窗口字段:16位,代表的是窗口的字節容量,也就是TCP的標准窗口最大為2^16 - 1 = 65535個字節(這個下面再詳細分析)

校驗和:源機器基於數據內容計算一個數值,收信息機要與源機器數值 結果完全一樣,從而證明數據的有效性。檢驗和覆蓋了整個的TCP報文段:這是一個強制性的字段,一定是由發送端計算和存儲,並由接收端進行驗證的。

緊急指針:是一個正偏移量,與序號字段中的值相加表示緊急數據最后一個字節的序號。TCP的緊急方式是發送端向另一端發送緊急數據的一種方式
選項與填充(必須為4字節整數倍,不夠補0):
最常見的可選字段的最長報文大小MSS(Maximum Segment Size),每個連接方通常都在一個報文段中指明這個選項。它指明本端所能接收的最大長度的報文段。
該選項如果不設置,默認為536(20+20+536=576字節的IP數據報)

 

3、TCP如何保證可靠性

1)應用數據被分割成TCP認為最合適發送的數據塊。稱為段(Segment)傳遞給IP層
2)當TCP發出一個段后,它會啟動一個定時器,等待目的端確認收到這個報文段。若沒有及時收到確認,將重新發送這個報文段
3)當TCP收到發自TCP連接另一端的數據,它將發送一個確認。這個確認不是立即發送的,通常將推遲幾分之一秒。
4)TCP將保持它首部和數據的校驗和,這是一個端到端的校驗和,目的是檢測數據在傳輸過程中的任何變化。如果收到段的校驗和有差錯,TCP將丟棄這個報文也不進行確認(對方就會重復發送了)。
5)TCP承載與IP數據報來傳輸,而IP數據報可能會失序,所以TCP的報文段到達時也可能會失序。但是TCP收到數據后會重新排序到正確的順序(通過序號)。
6)IP數據報會發生重復,TCP的接收端必須丟棄重復是數據
7)TCP還能提供流量控制,TCP連接的每一方都有一定大小的緩沖空間

 

 4、滑動窗口協議(也就是對包頭中窗口字段的理解)

參考1:https://www.cnblogs.com/ulihj/archive/2011/01/06/1927613.html

參考2:http://blog.chinaunix.net/uid-26275986-id-4109679.html

先上兩個概念:
通告接收窗口(rwnd):預防應用程序發送的數據超過對方的緩沖區,接收方使用的流量控制。
擁塞窗口(cwnd):預防應用程序發送的數據超過了網絡所能承載的能力。發送方使用的流量控制。
發送窗口:就是指上面兩者的較小值

由於TCP的全雙工的,所以其實TCP雙方各自都維護一個發送窗口和接收窗口。

假設是主機A發送給主機B
A和B都會維護一個數據幀的序列,這個序列稱為窗口。發送方的窗口大小由接收方確定。目的在於控制發送速度。以免接收方的緩存不夠大而導致溢出,同時流量控制也可以避免網絡擁塞。
這里其實是指A的發送窗口。


假設A發送了很多段給B,序號是1-10.這些段會處於種狀態:
1)已發送,已確認
2)已發送,未確認
3)等待發送
4)不允許發送

正常情況下,每個段都會由4狀態->3狀態->2狀態->1狀態。而窗口就是指處於狀態2和狀態3的總數。
由2狀態->1狀態的時候,窗口就會往后滑動一下,表示最近那個4狀態的段可以變成3狀態了。
如果接收方一直不確認,那么處於4狀態的段將永遠不會被發送。
當窗口滿了的時候,4狀態的段將不會變成3狀態。從而達到了控制發送速度的作用。

就像上圖一樣,123處於1狀態,456處於2狀態,789處於3狀態,10以后的處於4狀態。而窗口就是指哪個框起來的。這里為6。

隨着發送段被逐一的確認,這個窗口會往右滑動。

就像一個水池,總體積V,進水速度是s1,出水速度s2。當水池滿了就不能再注入了,強行注入會溢出丟失。窗口就是那個水池。

滑動窗口實現面向流的可靠性:

1)最基本的傳輸可靠性來源於確認重傳機制
2)滑動窗口的可靠性也是建立在確認重傳機制上的
3)發送窗口只有收到目的端口對本段發送窗口內字節的ACK確認,才會移動發送串口的左邊界。
4)接收窗口只有在前面所有的段都確認的情況下才會移動左邊界。當在前面還有段未收到確認,但是收到了后面段的情況下,窗口不會移動,也不對后續段進行確認。以此確保發送端會對這個數據重傳。

 

5、關於包頭中確認號ack的理解

 確認序號:僅當ACK標志為1時有效。確認號表示期望收到的下一個字節的序號

這里是拿三次握手之后,開始傳輸數據了進行分析。

服務器向客戶端發送一個數據包后,客戶端收到了這個數據包,會向服務器發送一個確認數據包。

傳輸數據的簡要過程如下:

1)發送數據:服務器向客戶端發送一個帶有數據的數據包。該數據包中的序列號和確認號與建立連接第三步的數據包找那個的序列號和確認號相同。

2)確認收到:客戶端收到該數據包,向服務器發送一個確認數據包。該數據包中,序列號是為上一個數據包中的確認號值。

而確認號為服務器發送的上一個數據包中的序列號+該數據包中所帶數據的大小。

回復確認收到的ack = 收到了序列號 + 數據的大小(同時也表示下一次期望收到的序號)

這里我們直接拿Wireshark抓包進行分析:

實例1:客戶端給服務器發送了”xcychongyong” 共13個字節。

先看,服務器收到的,也就是客戶端發送的:seq是10,數據長度是13.

再來看服務器發送給客戶端的確認包:根據上面的說明。ack應該是10 + 13 = 23

 

實例2:

如下圖,208(就是192.168.0.208)一共向182(就是192.168.0.182)發送了6組數據。

過濾條件:tcp and (ip.src==192.168.0.182 or ip.dst==192.168.0.182)

對於182來說:

第一次回應時ack是4,結果208下一次發送的序號就是4。

第二次回應時ack是10,結果208下一次發送的序號就是10。

第三次回應時ack是19,結果208下一次發送的序號就是19。

以此類推…

 

再來分析一個互相發送的:

如圖,一共發送了5次:

第一次182發給208,發的長度是7,seq是1.所以208回復的ack是8。也相當於告訴182:“182,你下次發的時候,序號就從8開始”。看第2個紅框,seq就是8.

第二次208發給182,發的長度是11,seq是1,所以182回復的ack是12。也相當於告訴208:“208,你下次發的時候,序號就從12開始”。看第2個綠框,seq就是12.

同理,

182再發送一次給208,seq應該是17  

208再發送一次給182,seq應該是33

 

ack表示期望下次接收到的序號。

那么ack是如何算出來的呢,就是通過收到的序號,和數據長度相加得來。

假設A收到B過來的數據(seq = 5,len = 15)。len表示數據長度。

那么A就會回復B,“剛才的數據我已經收到了,你接下來就發序號為20的包給我吧”。這樣就保證了數據不會亂序。

 綜上,確認號就是下一次將要收到包的序號。同時也等於發送方的序號+數據長度(確認號在ACK標志位有效時才有用。)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM