tcp通訊資料流分析 tcpdump

2022-05-03 19:18:10 字數 4703 閱讀 9314

socket中tcp的建立(三次握手)

tcp協議通過三個報文段完成連線的建立,這個過程稱為三次握手(three-way handshake),過程如下圖所示。

第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,並進入syn_send狀態,等待伺服器確認;syn:同步序列編號(synchronize sequence numbers)。

第二次握手:伺服器收到syn包,必須確認客戶的syn(ack=j+1),同時自己也傳送乙個syn包(syn=k),即syn+ack包,此時伺服器進入syn_recv狀態;

第三次握手:客戶端收到伺服器的syn+ack包,向伺服器傳送確認包ack(ack=k+1),此包傳送完畢,客戶端和伺服器進入established狀態,完成三次握手。

乙個完整的三次握手也就是: 請求---應答---再次確認。

對應的函式介面:

從圖中可以看出,當客戶端呼叫connect時,觸發了連線請求,向伺服器傳送了syn j包,這時connect進入阻塞狀態;伺服器監聽到連線請求,即收到syn j包,呼叫accept函式接收請求向客戶端傳送syn k ,ack j+1,這時accept進入阻塞狀態;客戶端收到伺服器的syn k ,ack j+1之後,這時connect返回,並對syn k進行確認;伺服器收到ack k+1時,accept返回,至此三次握手完畢,連線建立。

我們可以通過網路抓包的檢視具體的流程:

比如我們伺服器開啟9502的埠。使用tcpdump來抓包:

tcpdump -iany tcp port 9502

然後我們使用telnet 127.0.0.1 9502開連線.:

telnet 127.0.0.1 9502

14:12:45.104687 ip localhost.39870 > localhost.9502: flags [s], seq 2927179378, win 32792, options [mss 16396,sackok,ts val 255474104 ecr 0,nop,wscale 3], length 0(1)

14:12:45.104701 ip localhost.9502 > localhost.39870: flags [s.], seq 1721825043, ack 2927179379, win 32768, options [mss 16396,sackok,ts val 255474104 ecr 255474104,nop,wscale 3], length 0(2)

14:12:45.104711 ip localhost.39870 > localhost.9502: flags [.], ack 1, win 4099, options [nop,nop,ts val 255474104 ecr 255474104], length 0(3)

14:13:01.415407 ip localhost.39870 > localhost.9502: flags [p.], seq 1:8, ack 1, win 4099, options [nop,nop,ts val 255478182 ecr 255474104], length 7

14:13:01.415432 ip localhost.9502 > localhost.39870: flags [.], ack 8, win 4096, options [nop,nop,ts val 255478182 ecr 255478182], length 0

14:13:01.415747 ip localhost.9502 > localhost.39870: flags [p.], seq 1:19, ack 8, win 4096, options [nop,nop,ts val 255478182 ecr 255478182], length 18

14:13:01.415757 ip localhost.39870 > localhost.9502: flags [.], ack 19, win 4097, options [nop,nop,ts val 255478182 ecr 255478182], length 0

我們看到(1)(2)(3)三步是建立tcp:

第一次握手:

14:12:45.104687 ip localhost.39870 > localhost.9502: flags [s], seq 2927179378

客戶端ip localhost.39870 (客戶端的埠一般是自動分配的) 向伺服器localhost.9502 傳送syn包(syn=j)到伺服器》

syn包(syn=j) : syn的seq= 2927179378  (j=2927179378)

第二次握手:

14:12:45.104701 ip localhost.9502 > localhost.39870: flags [s.], seq 1721825043, ack 2927179379,

收到請求並確認:伺服器收到syn包,並必須確認客戶的syn(ack=j+1),同時自己也傳送乙個syn包(syn=k),即syn+ack包:

此時伺服器主機自己的syn:seq:y= syn seq 1721825043。

ack為j+1 =(ack=j+1)=ack 2927179379 

第三次握手:

14:12:45.104711 ip localhost.39870 > localhost.9502: flags [.], ack 1,

客戶端收到伺服器的syn+ack包,向伺服器傳送確認包ack(ack=k+1)

客戶端和伺服器進入established狀態後,可以進行通訊資料互動。此時和accept介面沒有關係,即使沒有accepte,也進行3次握手完成。

連線出現連線不上的問題,一般是網路出現問題或者網絡卡超負荷或者是連線數已經滿啦。

紫色背景的部分:

ip localhost.39870 > localhost.9502: flags [p.], seq 1:8, ack 1, win 4099, options [nop,nop,ts val 255478182 ecr 255474104], length 7

客戶端向伺服器傳送長度為7個位元組的資料,

ip localhost.9502 > localhost.39870: flags [.], ack 8, win 4096, options [nop,nop,ts val 255478182 ecr 255478182], length 0

伺服器向客戶確認已經收到資料

ip localhost.9502 > localhost.39870: flags [p.], seq 1:19, ack 8, win 4096, options [nop,nop,ts val 255478182 ecr 255478182], length 18

然後伺服器同時向客戶端寫入資料。

ip localhost.39870 > localhost.9502: flags [.], ack 19, win 4097, options [nop,nop,ts val 255478182 ecr 255478182], length 0

客戶端向伺服器確認已經收到資料

這個就是tcp可靠的連線,每次通訊都需要對方來確認。

6. tcp連線的終止(四次握手釋放)

建立乙個連線需要三次握手,而終止乙個連線要經過四次握手,這是由tcp的半關閉(half-close)造成的,如圖:

由於tcp連線是全雙工的,因此每個方向都必須單獨進行關閉。這個原則是當一方完成它的資料傳送任務後就能傳送乙個fin來終止這個方向的連線。收到乙個 fin只意味著這一方向上沒有資料流動,乙個tcp連線在收到乙個fin後仍能傳送資料。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

(1)客戶端a傳送乙個fin,用來關閉客戶a到伺服器b的資料傳送(報文段4)。

(2)伺服器b收到這個fin,它發回乙個ack,確認序號為收到的序號加1(報文段5)。和syn一樣,乙個fin將占用乙個序號。

(3)伺服器b關閉與客戶端a的連線,傳送乙個fin給客戶端a(報文段6)。

(4)客戶端a發回ack報文確認,並將確認序號設定為收到序號加1(報文段7)。

對應函式介面如圖:

過程如下:

這樣每個方向上都有乙個fin和ack。

1.為什麼建立連線協議是三次握手,而關閉連線卻是四次握手呢?

這是因為服務端的listen狀態下的socket當收到syn報文的建連請求後,它可以把ack和syn(ack起應答作用,而syn起同步作用)放在乙個報文裡來傳送。但關閉連線時,當收到對方的fin報文通知時,它僅僅表示對方沒有資料傳送給你了;但未必你所有的資料都全部傳送給對方了,所以你可以未必會馬上會關閉socket,也即你可能還需要傳送一些資料給對方之後,再傳送fin報文給對方來表示你同意現在可以關閉連線了,所以它這裡的ack報文和fin報文多數情況下都是分開傳送的。

2.為什麼time_wait狀態還需要等2msl後才能返回到closed狀態?

這是因為雖然雙方都同意關閉連線了,而且握手的4個報文也都協調和傳送完畢,按理可以直接回到closed狀態(就好比從syn_send狀態到establish狀態那樣);但是因為我們必須要假想網路是不可靠的,你無法保證你最後傳送的ack報文會一定被對方收到,因此對方處於last_ack狀態下的socket可能會因為超時未收到ack報文,而重發fin報文,所以這個time_wait狀態的作用就是用來重發可能丟失的ack報文。

TCP互動資料流 成塊資料流

tcp資料流分類 基於tcp的各類解決方案,可以根據資料吞吐量來大致分成兩大類 1 互動資料型別,例如telnet,ssh,這種型別的協議在大多數情況下只是做小流量的資料交換,比如說按一下鍵盤,回顯一些文字等等。2 資料成塊型別,例如ftp,這種型別的協議要求tcp能盡量的運載資料,把資料的吞吐量做...

TCP 互動資料流

tcp通訊量如果按分組數量計算,約一半的tcp報文段包含成塊資料 如ftp 電子郵件和usenet新聞 另一半則包含互動資料 如telnet,rlogin 如果按位元組計算,則成塊資料與互動資料的比例約為90 和10 這是因為成塊資料報文段基本上是滿長度的,而互動式資料則小得多。tcp同時處理這兩類...

資料流與通訊

資料流 大b 小b區別 b byte 位元組 b bit 位元 1b 8b 位元率 位元率規定使用 位元每秒 bit s或bps 為單位,經常和國際單位制詞頭關聯在一起,如 千 kbit s或kbps 兆 mbit s或mbps 吉 gbit s或gbps 和 太 tbit s或tbps 在電信和電...