本篇文章是使用wireshrak對某個https請求的tcp包進行分析。算法
經過抓包實際分析瞭解tcp包。緩存
在我本身機子上安裝的是wireshark2.2.6版本,隨機查找了某個TCP鏈接,並跟蹤流。
服務器
SYN
請求鏈接,此時客戶端發送的seq=0,ack=0。SYN+ACK
確認鏈接,此時服務端發送的seq=0,ack=1。No81:客戶端接收到服務端的SYN+ACK
向服務端響應ACK
包,此時客戶端發送的seq=1,ack=1。網絡
因爲抓到的tcp是使用了https協議,建裏鏈接須要先進行認證,步驟以下圖所示。
tcp
No84: 客戶端向服務端發起握手請求,具體包格式及內容這裏不作詳細分析。
加密
這裏SSL總長度爲239字節(其中
ContentType
爲1字節,Version
爲2字節,Length
爲2字節,再加上後續握手協議長度234。)。.net
ACK
包,此時seq=1,ack=1。這個發送的是一個特殊的TCP Window Update
,服務端告知客戶端服務端有足夠的緩存大小(8192),能夠正常接收客戶端數據。若出現了TCP Window Full
包表示緩存區已滿,客戶端會中止發送,直到接收到了TCP Window Update
包。(Window值表示滑動窗口1,容許接收到多個包同時響應一個ACK包)No104: 服務器向客戶端發送握手,因爲服務端須要返回證書、算法等信息,所以包可能會大於1460字節,會發生拆包現象(No136可看到該包總大小爲5984KB,拆分了5個包發送)。當前服務端發送的seq=1,ack=240(當前包大小爲1460,No84說明客戶端包大小爲239。)
3d
TCP Previous segment not captured
,說明發送包可能出現了亂序或丟包現象,這個包的seq=2921,而No104的下一個包seq應該爲1461,No104和No105中間seq=1461的包可能丟包或亂序傳輸。ACK
其中ack=1461,表示客戶端確認收到了No104這個包。ACK
包,這個包標記的是TCP Out-Of-Order
,因爲No105包顯示出現了丟包現象,所以tcp將No104之前的包所有重傳,這個包實際就是No104。ACK
包,這個包標記的是TCP Dup ACK 108#1
,表示重傳ACK包,這個包是因爲No118包引發的(#N表示重傳N次,這裏重傳了1次),由於No118包服務端向客戶端發送了一個亂序的包,而客戶端在No108包已經確認接收到No104這個包,seq應該爲1461,因此,客戶端再一次重傳108包告知服務端客戶端已經接收到No104包,這個包實際服務端已經接收到了所以會被丟棄。TCP Retransmission
,兩個包的seq分別爲1461和2921,因爲服務端認爲已經發了這兩個包(實際seq=1461的包沒發,由No105可看出,seq=2921的包發了,可是客戶端沒有響應響應的ACK包),而後長時間收不到客戶端的ACK包,所以服務端會重發這兩個包。ACK
包。seq=240,ack=5841,表示已經接收到服務端seq=5841之前的全部包。TCP Spurious Retransmission
,表示這個包已經發送過。該報的seq=1461,即No123重傳的包,雖然客戶端向服務端發送了ACK
包收到了seq=5841之前的包,可是服務端可能沒有收到這個ACK包。ACK
包。seq=240,ack=5841。包標記的是TCP Dup ACK 127#1
。因爲客戶端在No127已經返回了ack=5841,可是服務端在No132仍是重傳了以前已經傳過的包,因此客戶端認爲No127包可能服務端沒有收到,全部這裏重傳了No127這個ACK包,這個包服務端已經接收到了,所以會被丟棄。No140:客戶端向服務端發送ACK
包。seq=240,ack=5985。
code
ACK
包。這個包標記爲TCP Dup ACK 140#1
是因爲No147這個包服務端發生虛假重傳,所以客戶端從新發送No140包。Change Cipher Spec, Encrypted Handshake Message
,這是對握手信息進行加密。No171: 客戶端發送給服務端ACK包,確認收到No170這個包。
No179: 客戶端發送給服務端ACK包,seq=8331,ack=8770,確認收到No178這個包。
No152到No179都是正常傳輸的包,這裏不作詳細分析了。
FIN
包,同時客戶端進入到FIN_WAIT_1
狀態。理論上服務端發送完就主動關閉http鏈接, 可是抓包看確是客戶端先發送的
FIN+ACK
包,所以說明服務端發送的FIN+ACK
的包可能丟包,客戶端沒收到或收到慢了。
FIN+PSH+ACK
,seq=7552,ack=8331。這包不但傳了FIN
關閉鏈接,又傳了PSH
。說明No178包服務端發出來,客戶端返回的ACK包(No179以及No180)服務端沒收到(這中間可能網絡處理問題)。TCP Out-Of-Order
,所以客戶端認爲服務端的包亂序了,所以,所以客戶端重傳No179。FIN
包,也接受到No188包,返回客戶端一個ACK
包,seq也更新成最新的8770,客戶端進入FIN_WAIT_2
狀態。上面抓的包經分析可能出現屢次網絡異常或網絡波動,出現了亂序,重傳,虛假重傳及鏈接重置等TCP包。
若分析有誤,但願加以指正。
本文地址:http://www.javashuo.com/article/p-ztvcbzns-bd.html
做者博客:傑哥很忙
歡迎轉載,請在明顯位置給出出處及連接
使用TCP的滑動窗口協議時,接收方沒必要確認每個收到的分組。在TCP中,ACK是累積的—它們表示接收方已經正確收到了一直到確認序號減1的全部字節。↩