網絡抓包分析TCP協定的可靠性
- 确認應答機制
-
- 從三次握手的角度而言
- 從發送消息的角度看
- 逾時重傳機制
- 滑動視窗機制
- 擁塞控制機制
-
- 慢啟動與擁塞避免
- 快重傳
- 快恢複
- 捎帶應答機制
- 延時應答機制
- 保活計時器
Tcp協定的特點就是面向連接配接, 傳輸可靠
,面向位元組流
抓包的工具:linux下使用
tcpdump
,windows下使用
wireshark
抓包過程:
- 先在linux下,使用
指令監聽将要通信的端口,擷取通信過程中的資料資訊tcpdump
- 再在windows下使用
打開資料資訊,開始死磕的過程。。。。。wireshark

可靠傳輸的原因:機制
确認應答
機制
逾時重傳
機制
滑動視窗
機制
擁塞控制
機制
捎帶應答
機制
延時應答
确認應答機制
- 當發送方發送一個封包的時候,需要帶上序号。
- 接收方收到封包後,需要對該封包進行确認。也就是給對方發送一個确認封包,封包中的确認序号就是告訴對方,自己期望的下一個序号
從三次握手的角度而言
第一步:讓服務端确定用戶端的發送資料的能力
第二步:讓用戶端确定服務端的接收資料和發送資料的能力
第三步:讓服務端知道用戶端接收資料的能力
![]()
傳輸層(二)網絡抓包分析TCP協定的傳輸可靠性确認應答機制逾時重傳機制滑動視窗機制擁塞控制機制捎帶應答機制延時應答機制保活計時器
- 連接配接發起方率先向對端發起連接配接請求(SYN),并協商了一個序列号
(Seq=0)
- 被動連接配接方收到了發起方的連接配接請求,他收到了連接配接方為0的序号,再告訴給連接配接方我想要你的下一個序号
,這裡是0+1
然後再告訴對方自己的起始序号,這裡是(ACK=1)
(Seq=0)
- 連接配接方收到了對方确認的信号,回複對方期待的資料
,并确認自己收到了對方的期待的信号(Seq=1)
(Ack=1)
SYN(Seq=0)
這是連接配接發起方告訴對端,我要連接配接拉,起始序号是0,并且消耗了0這個序号。
ACK(Ack=1) + SYN(Seq=0)
這個過程分為兩步:
- 首先是被動連接配接方收到了連接配接方的SYN封包,知道了對端發送SYN封包的序号為0,告訴對方自己收到了這個0,告訴的方式就是發送下一步所期待的封包的序号,也就是
,0+1
ACK(Ack=1)
- 然後再告訴連接配接方,自己的起始序号,并且消耗掉了這個序号,告訴的方式就是
SYN(Seq=0)
ACK(Seq=1,ACK=1)
這個過程也是分為兩步
- 連接配接方收到了對方發送的序号為0的資料包,并告訴對方,我想要你之後發送的資料包的序号是從0+1開始的,也就是
ACK=1
-
,告訴對方,我這個ACK維護的資料序号是1,但是我這個ACK沒有消耗這個序号Seq=1
三次握手之後
對于連接配接發起方而言:自己維護序号的有效範圍是
對于被動連接配接方而言:自己維護序号的有效範圍是
1 ~ 2^32
1 ~ 2^32
對于一次三次握手而言,雙方在發送第一個資料包的時候(三次握手的前兩個步驟),可以說是一個彼此協商起始序号位置的過程。對于每一個連接配接雙方而言,自己所管理的序号是
不一定從0開始
的。
對于連接配接發起方和被動連接配接方而言,他們在通信的過程中各自維護這一套序号,範圍都是
0 ~ 2^32
。
–> 會消耗序号
SYN
--> 不會消耗序号
ACK
對于三次握手的過程而言,前兩個過程是一個通信雙方互相協商自己起始序号的一個過程,第三步是一個确認收到的過程
三次握手的過程可以發送資料嗎?
前兩次協商起始序号的時候,是不能發送資料的。因為TCP協定是面向連接配接,要是有人用大量随機的ip加上大量資料,直接在第一步的時候就發送給對端,那麼對端就會陷入接收資料的邏輯中,然後在第二步回應的時候,因為對方的ip本身就是随機的,不存在,又會陷入等待的邏輯,很容易會造成阻塞。
但是第三次握手的過程是可以發送資料的,因為這個時候雙方已經協商完畢了,用戶端已經知道服務端可以接收資料,是以可以帶着資料去驗證服務端的接收能力
從發送消息的角度看
在這個過程中,一共發送了兩條資料,一次是用戶端給服務端發送了
nihao
,另一次是服務端回複用戶端
haode
- 用戶端給服務端發送了
這個時候,用戶端和服務端維護的起始序号都是1nihao
PSH(Seq=1)ACK(ACK=1) len=5
這是用戶端率先給服務端發送的資料,“nihao”
PSH
表示發送資料
Seq=1
,表示從用戶端序号為1處開始發送資料,發送的資料長的是
len=5
。其中,每個序号代表一個位元組的資料,資料一共5個位元組,是以說在這個過程中消耗了用戶端
5個序号
,也就是說下一次用戶端的有效序号是
seq=6
ACK=1
,表示用戶端知道服務端下一條有效的序号是1,就發送這樣一個封包,期待服務端的下一條
Seq=1
的消息
ACK(Seq=1,ACK=6) len=0
這是服務端在接收到消息"nihao"後,給用戶端的應答,整個應答的過程都是ACK封包,ACK封包不會消耗有效序号的
Seq=1
,告訴用戶端,自己目前的有效序号是1
len=0
,表示自己沒有發送資料
ACK=6
,表示服務端收到了用戶端發送的5個位元組的資料,然後期待
seq=1+5
,也就是序号為6的資料
- 服務端給用戶端回複資料
這個時候,用戶端維護的起始序号是6,服務端是1haode
PSH(Seq=1),ACK(ACK=6) len=5
這是服務端回複給用戶端的資料
"haode"
Seq=1
,表示服務端目前的有效序号是1,發送
len=5
的資料,整個過程一共消耗服務端5個序号
ACK=6
,表示确認用戶端下一個封包的序号是6,并期待用戶端seq=6的消息
ACK(Seq=6,ACK=6) len=0
這是用戶端對
"haode"
資料的應答,整個過程為ACK,不消耗有效序号
Seq=6
,告訴服務端,自己現在的有效序号是
seq=6
,本次資料的長度
len=0
,沒有發送資料
ACK=6
,期待服務端發送下一個
seq=6
的資料,也就是自己收到了你發的len=5的資料
總結:
ACK :自己期待對方發送的資料序号,自己目前的起始資料序号
PSH :自己發送資料的起始序号,資料長度,期待對方回複的消息序号
逾時重傳機制
當消息發送方發送一條消息之後,就會開啟一個重傳計時器,用來計算消息發送出去的時間。
當消息發送出去的時間大于RTO的時候,還沒有收到對方的确認封包,就預設發生了丢包,則進行重傳封包
RTO:逾時重傳的時間。這個時間是動态計算出來的,因為網絡有時很快,有時很慢
RTO = 2 * RTT
RTT :封包往返時間
從發送封包開始計算,直到收到确認應答,所經曆的時間就是往返封包的時間
滑動視窗機制
之前所畫的消息發送的圖檔,都是
一個消息+一個應答
的形式,這樣發好像效率有點慢,是以在TCP協定中有一個
滑動視窗的機制
。
視窗
:他其實就是已經被發送方發送到網絡上,但是還沒有确認的資料集合
有了滑動視窗的機制,就不必讓發送方等待确認封包到達之後,才發送下一條封包。而是允許發送方同時發送多組封包到達網絡上,但是這并不意味着對方不需要進行确認應答
分組
:TCP協定的通信雙方在發送資料的時候,都維護着一個起始序号,那麼根據這個序号,就可以對每次發送的資料進行分類。分組也就是TCP發送資料流序号的集合
既然是滑動視窗,那麼肯定有一個視窗的大小,這個大小是根據雙方網絡的轉發能力來動态絕對的
- 網絡好的時候,視窗就會變大,以便發送更多的資料
- 網絡比較差的時候,視窗就會變小,讓資料發送的慢一點
一開始在三次握手的連接配接過程中,通信雙方其實也是一個協商滑動視窗大小的過程
最後的視窗大小 43776 = 342 * 128
視窗的大小 = 允許不接收到确認應答,就發送到網絡上的分組數量
對于TCP的通信雙方而言,他們都會互相維護一套自己的視窗
- 發送視窗:儲存的是沒有确認的封包,這是發送緩沖區的一部分
- 接收視窗:儲存接收到的封包,和接收緩沖區的作用差不多
視窗移動的條件
:一定要最早的分組确定應答之後,視窗才可以向後滑動(類似于雙指針的題目,left指針負責縮小視窗,right負責放大視窗)
既然是資料發送,那麼肯定存在丢包的情況,滑動視窗是如何解決丢包情況的呢?
- 資料丢失
對于消息接收方而言,如果沒有收到消息發送方發送的資料,即使自己接收到了更大序号的資料,也不會進行确認回複。而是一直确認回複丢失掉的封包的起始序号。
- 應答丢失
如果發送方接收到比未确定的序号更大的确認序号的時候,就認為沒有确認的小的序号對方一定收到了,這個小序号的封包對方就不用重發了
原理:
如果消息發送方沒有收到小的封包,但是收到了序号大的封包。說明對方一定是收到了小的序号封包,不然不會發送大的封包的确認資訊的
是以說,如果發送方收到了更大的确認序号,但是沒有收到小的确認序号,就會忽略,不需要重傳
擁塞控制機制
慢啟動與擁塞避免
核心思想就是,通信雙方在建立連接配接後,一開始不要發送大量的資料,而是先發送少量資料,探測一下網絡擁塞的程度。
當網絡情況比較好的時候,才逐漸發送大量資料
擁塞視窗
:cwnd(congestion window),通信雙方在發送資料的時候,不單單要考慮自己的發送視窗,還有考慮擁塞視窗的大小。
擁塞視窗的大小一般等于發送視窗的大小
- 當擁塞視窗小于發送視窗的大小時,安裝擁塞視窗的大小發送資料
慢開始門限
:這可以了解為是一個門檻值(ssthresh),一開始是16
- 當擁塞視窗的大小小于慢開始門限的時候,就執行慢開始算法;
- 當超過慢開始門限的時候,執行擁塞避免算法
TCP協定的通信雙方,在三次握手期間就在協商視窗的大小,等到第三次握手的時候,就确定了一個一緻大小的視窗
之後在每次通信的時候,都會帶有一個視窗的大小,這是在告訴對方自己的接收能力,以便可以動态的更新視窗大小
當擁塞視窗小于慢開始門限的時候,執行慢開始算法,擁塞視窗的大小随着傳輸的輪次呈指數增長。
等到擁塞視窗大小大于慢開始門限的時候,就執行擁塞避免算法,擁塞視窗的大小随着傳輸輪次呈線性增長
快重傳與快恢複
很多情況下,發送方都會收到對方的重複的确認封包段,就像TCP封包段丢失,接收方收到亂序的TCP封包段并進行重排等。
擁塞控制算法需要判斷當收到重複的确認封包段的時候,網絡是否真的發生了擁塞,或者說TCP封包段是否丢失了。
具體的做法是,當發送方收到3個重複的确認封包段,就認為是擁塞發生了,這時就需要執行快重傳和快恢複算法來處理擁塞
快重傳
核心思想: 當接收方接收到一個資料的封包段的時候,就發出重複的确認,就是想提前告訴發送方有一個資料沒有收到,發生了丢失
對于發送方而言,每發送一個封包,就會開啟一個重傳計時器,然後等待RTO的時間沒有收到确認封包,就開始重傳。
但是對于快重傳而言,當接收方一連串發送的三個重複确認封包時,發送方就不需要等待設定的重傳計時器,就會直接重傳丢失的封包。
重傳之後,接收方再次回複确認報的時候,回複的是所有收到的資料報中,不連續的下一個序号,不一定是剛重傳之後的序号。
快重傳依賴接收方發送的連續的重複确認資料報,不會等待接收方進行捎帶應答确認
快恢複
對于發送方而言,如果一連串接收到三個重複的确認包,就會認為網絡擁塞的不是很嚴重,因為都一次性接收到三個确認包了。
這就不需要從慢開始進行傳輸,而是重新設定慢開始門限,将擁塞視窗的大小等于新的慢開始門限,進而執行擁塞避免算法
新的慢開始門限 = 擁塞視窗 / 2
捎帶應答機制
為了減少網絡當中的資料量,當接收方收到一個資料的時候,如果需要回複資料,就把這個資料随着确認收到的封包一起發送給對方
延時應答機制
和捎帶應答機制差不多,都是為了減少網絡中資料包的數量,進而防止網絡擁塞。
具體的做法,就是雙方在發送資料的時候,順便告訴對方自己現在的接收資料的能力,也就是自己還能接收多少資料。
這個時候,如果接收方收到發送方發送的資料後,将接收的資料放在接收緩沖區中,但是這個時候接收緩沖區滿了,就會向對方回複确認消息時,加上
Win=0
的封包
這個時候的處理方式有兩種
- 等待應用程式從接收緩沖區中把資料讀走,這個時候接收方就會更新自己視窗的大小,然後告訴對方自己現在的視窗大小
2. 發送方在等待一個RTO時間後,詢問對方視窗的大小,發送一個視窗探測包
延時應答在具體處理資料的時候,還有着這樣的特點:
- 當接收方收到資料後,先等待200ms,等待應用層将緩沖區中的資料讀走,進而擴大接收緩沖區的能力
- 再回複的時候,盡量告訴發送方在自己接收能力大的時候,自己接收緩沖區的大小
- 延時應答不是不應答,而是不立即确認,會等待一段時間再發送确認包
保活計時器
如果通信雙方長時間沒有進行通信,是以就不知道對方是否連接配接正常,這時就用報活計時器來探測
他的作用就是保證TCP的連接配接是正常的
産生的條件:目前連接配接在2小時内都沒有發送資料了,就發生一個保活探測包
在發送這個包的時候,發送方每隔75s發送一個保活探測包,連續發送10次,如果這10次都沒有收到确認,則認為連接配接異常,需要斷開連接配接。
但是如果這個期間,有一次對方發生了回應,就說明連接配接正常,就會重置保活計時器,從0開始