2021-05-12 14:32:11
TCP協定基礎知識及wireshark抓包分析實戰
TCP相關知識
應swoole長連線開發調研相關TCP知識並記錄。
資料封包流程
如圖,如果我需要傳送一條資料給使用者,實際的大小肯定是大於你傳送的大小,在各個資料層都進行了資料的封包,以便你的資料能完整的發給你想要的使用者。
乙太網的封包的負載是1500位元組,IP包頭需要20個位元組,TCP的包頭需要20個位元組,實際的資料內容大小則是1460個位元組,如圖:
OSI模型術語
應用層:
如nginx、swoole等,大部分的資料都只需要關心應用層即可,我需要傳輸什麼資料,我只需要呼叫對應的方法、傳送給已知的IP、埠即可。
TCP層:
對應用層的資料進行包裝,TCP的報文格式如下圖,TCP/UDP層規定了資料的交換格式,如何進行握手、連結,如果加快資料傳輸、保證資料的完整性等。
TCP層主要有幾個演算法可以關注下:
慢啟動、擁塞避免、快速重傳、快恢復、滑動視窗
IP層:
細心的人也許已經發現TCP報文格式只有你傳送的源埠和目標埠,並沒有要傳送的IP地址和你的IP地址,這些其實都封包在IP層
資料鏈路層:
資料轉換為frame(幀)進行資料傳輸,為終端通訊提供傳輸媒體和連結,常用裝置有網絡卡、交換機等
物理層:
傳輸位元流,物理裝置傳輸的層,屬於硬體領域範疇,如光纖裝置
TCP報文格式
Wireshark抓的某個包截圖:
TCP報文格式說明
1、埠號:用來標識同一台計算機的不同的應用進程。
1)源埠:源埠和IP地址的作用是標識報文的返回地址。
2)目的埠:埠指明接收方計算機上的應用程式介面。
TCP報頭中的源埠號和目的埠號同IP資料包中的源IP與目的IP唯一確定一條TCP連線。
2、序號和確認號:是TCP可靠傳輸的關鍵部分。序號是本報文段傳送的資料組的第一個位元組的序號。在TCP傳送的流中,每一個位元組一個序號。e.g.一個報文段的序號為300,此報文段資料部分共有100位元組,則下一個報文段的序號為400。所以序號確保了TCP傳輸的有序性。確認號,即ACK,指明下一個期待收到的位元組序號,表明該序號之前的所有資料已經正確無誤的收到。確認號只有當ACK標誌為1時才有效。比如建立連線時,SYN報文的ACK標誌位為0。
3、資料偏移/首部長度:4bits。由於首部可能含有可選項內容,因此TCP報頭的長度是不確定的,報頭不包含任何任選欄位則長度為20位元組,4位元首部長度欄位所能表示的最大值為1111,轉化為10進位制為15,15*32/8 = 60,故報頭最大長度為60位元組。首部長度也叫資料偏移,是因為首部長度實際上指示了資料區在報文段中的起始偏移值。
4、保留:為將來定義新的用途保留,現在一般置0。
5、控制位:URG ACK PSH RST SYN FIN,共6個,每一個標誌位表示一個控制功能。
1)URG:緊急指標標誌,為1時表示緊急指標有效,為0則忽略緊急指標。
2)ACK:確認序號標誌,為1時表示確認號有效,為0表示報文中不含確認資訊,忽略確認號欄位。
3)PSH:push標誌,為1表示是帶有push標誌的資料,指示接收方在接收到該報文段以後,應儘快將這個報文段交給應用程式,而不是在緩衝區排隊。
4)RST:重置連線標誌,用於重置由於主機崩潰或其他原因而出現錯誤的連線。或者用於拒絕非法的報文段和拒絕連線請求。
5)SYN:同步序號,用於建立連線過程,在連線請求中,SYN=1和ACK=0表示該資料段沒有使用捎帶的確認域,而連線應答捎帶一個確認,即SYN=1和ACK=1。
6)FIN:finish標誌,用於釋放連線,為1時表示傳送方已經沒有資料傳送了,即關閉本方資料流。
6、視窗:滑動視窗大小,用來告知傳送端接受端的快取大小,以此控制傳送端傳送資料的速率,從而達到流量控制。視窗大小時一個16bit欄位,因而視窗大小最大為65535。
7、校驗和:奇偶校驗,此校驗和是對整個的 TCP 報文段,包括 TCP 頭部和 TCP 資料,以 16 位字進行計算所得。由傳送端計算和儲存,並由接收端進行驗證。
8、緊急指標:只有當 URG 標誌置 1 時緊急指標才有效。緊急指標是一個正的偏移量,和順序號欄位中的值相加表示緊急資料最後一個位元組的序號。 TCP 的緊急方式是傳送端向另一端傳送緊急資料的一種方式。
9、選項和填充:最常見的可選欄位是最長報文大小,又稱為MSS(Maximum Segment Size),每個連線方通常都在通訊的第一個報文段(為建立連線而設定SYN標誌為1的那個段)中指明這個選項,它表示本端所能接受的最大報文段的長度。選項長度不一定是32位元的整數倍,所以要加填充位,即在這個欄位中加入額外的零,以保證TCP頭是32的整數倍。
10、資料部分: TCP 報文段中的資料部分是可選的。在一個連線建立和一個連線終止時,雙方交換的報文段僅有 TCP 首部。如果一方沒有資料要傳送,也使用沒有任何資料的首部來確認收到的資料。在處理超時的許多情況中,也會傳送不帶任何資料的報文段。
TCP三次握手圖形
IP報文格式參考
IP報文是對TCP的資料進行了一次包裝,再傳送給資料鏈路層,IP報文格式固定格式為20個位元組,如圖:
更多協定(IP TCP UDP)的報文格式參考:
http://blog.51cto.com/mmanong/1962353
TCP 視窗大小(cwnd)
TCP慢啟動
當第一次進行SYN建立連結的時候,用戶端會與伺服器端進行溝通MSS的大小,一般為1460 Byte,每當有一個報文欄位被確認,cwnd就增加一個MSS大小,這樣隨著網路時間RTT的呈指數級增長,但是也不會一直指數級別增加,會有一個最大值的限制
資料測試
伺服器端指令碼(swoole)
<?php
$server
=
new
swoole_server(
"::"
, 9503);
$server
->on(
'connect'
,
function
(
$server
,
$fd
){
echo
"connection open: {$fd}n"
;
});
$server
->on(
'receive'
,
function
(
$server
,
$fd
,
$reactor_id
,
$data
) {
$server
->send(
$fd
,
"Swoole: {$data}"
);
$server
->close(
$fd
);
});
$server
->on(
'close'
,
function
(
$server
,
$fd
) {
echo
"connection close: {$fd}n"
;
});
$server
->start();
Wireshark抓包
用戶端傳送資料後進行抓包,如圖:
Wireshark流程統計檢視
統計-流量圖-顯示過濾器的限制,選擇TCP Flows:
從結果可以看到tcp從SYN、ACK、FIN的整個過程及每個過程的耗時情況。
TCP視窗大小調研結論
1、 TCP一次封包傳送資料大小不能超過MMS設定,一般為1460位元組
2、 TCP慢啟動特性在初始傳輸資料的時候並不是直接傳送1460資料,而通過慢啟動演算法指數遞增,演算法本身不支援進行引數改動
相關文章