最近有很多同事開始學習Wireshark,他們遇到的第一個困難就是理解不了主界面上的提示信息,因而跑來問我。問的人多了,我也總結成一篇文章,但願對你們有所幫助。Wireshark的提示但是其最有價值之處,對於初學者來講,若是能理解這些提示所隱含的意義,學起來定能事半功倍。緩存
1.[Packet size limited during capture]服務器
當你看到這個提示,說明被標記的那個包沒有抓全。以圖1的4號包爲例,它全長有171字節,但只有前96個字節被抓到了,所以Wireshark給了此提示。網絡
圖1tcp
這種狀況通常是由抓包方式引發的。在有些操做系統中,tcpdump默認只抓每一個幀的前96個字節,咱們能夠用「-s」參數來指定想要抓到的字節數,好比下面這條命令能夠抓到1000字節。工具
[root@my_server /]# tcpdump -i eth0 -s 1000 -w /tmp/tcpdump.cap性能
2.[TCP Previous segment not captured]學習
在TCP傳輸過程當中,同一臺主機發出的數據段應該是連續的,即後一個包的Seq號等於前一個包的Seq+Len(三次握手和四次揮手是例外)。若是Wireshark發現後一個包的Seq號大於前一個包的Seq+Len,就知道中間缺失了一段數據。假如缺失的那段數據在整個網絡包中都找不到(即排除了亂序),就會提示[TCP Previous segment not captured]。好比在圖2這個例子中,6號包的Seq號1449大於5號包的Seq+Len=1+0=1,說明中間有個攜帶1448字節的包沒被抓到,它就是「Seq=1, Len=1448」。spa
圖2操作系統
網絡包沒被抓到還分兩種狀況:一種是真的丟了;另外一種是實際上沒有丟,但被抓包工具漏掉了。在Wireshark中如何區分這兩種狀況呢?只要看對方回覆的確認(Ack)就好了。若是該確認包含了沒抓到的那個包,那就是抓包工具漏掉而已,不然就是真的丟了。3d
順便分析一下圖2這個網絡包,它是HTTPS傳輸異常時在客戶端抓的。由於「Len: 667」的小包(即6號包)能夠送達,但「Len: 1448」的大包卻丟了,說明路徑上可能有個網絡設備的MTU比較小,會丟棄大包。後來的解決方式證明了這個猜想,只要把整個網絡路徑的MTU保持一致,問題就消失了。
3.[TCP ACKed unseen segment]
當Wireshark發現被Ack的那個包沒被抓到,就會提示 [TCP ACKed unseen segment]。這多是最多見的Wireshark提示了,幸虧它幾乎是永遠能夠忽略的。以圖3爲例,32號包的Seq+Len=6889+1448=8337,說明服務器發出的下一個包應該是Seq=8337。而咱們看到的倒是35號包的Seq=11233,這意味着8337~11232這段數據沒有被抓到。這段數據本應該出如今34號以前,因此Wireshark提示了[TCP ACKed unseen segment]。
圖3
不難想象,在一個網絡包的開頭會常常看到這個提示,由於只抓到了後面的Ack但沒抓到前面的數據包。
4.[TCP Out-of-Order]
在TCP傳輸過程當中(不包括三次握手和四次揮手),同一臺主機發出的數據包應該是連續的,即後一個包的Seq號等於前一個包的Seq+Len。也能夠說,後一個包的Seq會大於或等於前一個包的Seq。當Wireshark發現後一個包的Seq號小於前一個包的Seq+Len時,就會認爲是亂序了,所以提示 [TCP Out-of-Order] 。如圖4所示,3362號包的Seq=2685642小於3360號包的Seq=2712622,因此就是亂序。
圖4
小跨度的亂序影響不大,好比本來順序爲1、2、3、4、5號包被打亂成2、1、3、4、5就沒事。但跨度大的亂序卻可能觸發快速重傳,好比打亂成2、3、4、5、1時,就會觸發足夠多的Dup ACK,從而致使1號包的重傳。
5.[TCP Dup ACK]
當亂序或者丟包發生時,接收方會收到一些Seq號比指望值大的包。它每收到一個這種包就會Ack一次指望的Seq值,以此方式來提醒發送方,因而就產生了一些重複的Ack。Wireshark會在這種重複的Ack上標記[TCP Dup ACK] 。
以圖5爲例,服務器收到的7號包爲「Seq=29303, Len=1460」,因此它指望下一個包應該是Seq+Len=29303+1460=30763,沒想到實際收到的倒是8號包Seq=32223,說明Seq=30763那個包可能丟失了。所以服務器當即在9號包發了Ack=30763,表示「我要的是Seq=30763」。因爲接下來服務器收到的10號、12號、14號也都是大於Seq=30763的,所以它每收到一個就回復一次Ack=30763,從圖中可見Wireshark在這些回覆上都標記了[TCP Dup ACK]。
圖5
6.[TCP Fast Retransmission]
當發送方收到3個或以上[TCP Dup ACK],就意識到以前發的包可能丟了,因而快速重傳它(這是RFC的規定)。以圖6爲例,客戶端收到了4個Ack=991851,因而在1177號包重傳了Seq=991851。
圖6
7.[TCP Retransmission]
若是一個包真的丟了,又沒有後續包能夠在接收方觸發[Dup Ack],就不會快速重傳。這種狀況下發送方只好等到超時了再重傳,此類重傳包就會被Wireshark標上[TCP Retransmission]。以圖7爲例,客戶端發了原始包(包號1053)以後,一直等不到相應的Ack,因而只能在100多毫秒以後重傳了(包號1225)。
圖7
超時重傳是一個很是有技術含量的知識點,好比等待時間的長短就大有學問,本文就不細說了,畢竟須要懂這個的人不多。
8.[TCP zerowindow]
TCP包中的「win=」表明接收窗口的大小,即表示這個包的發送方當前還有多少緩存區能夠接收數據。當Wireshark在一個包中發現「win=0」時,就會給它打上「TCP zerowindow」的標誌,表示緩存區已滿,不能再接受數據了。好比圖8就是服務器的緩存區已滿,因此通知客戶端不要再發數據了。咱們甚至能夠在3258~3263這幾個包中看出它的窗口逐漸減小的過程,即從win=15872減少到win=1472。
圖8
9.[TCP window Full]
當Wireshark在一個包中打上[TCP window Full]標誌時,就表示這個包的發送方已經把對方所聲明的接收窗口耗盡了。以圖9爲例,Britain一直聲明它的接收窗口只有65535,意味着Middle East最多能給它發送65535字節的數據而無需確認,即「在途字節數」最多爲65535字節。當Wireshark在包中計算出Middle East已經有65535字節未被確認時,就會發出此提示。至於Wireshark是怎麼計算的,請參考本書的《計算「在途字節數」》一文。
圖9
[TCP window Full]很容易跟[TCP zerowindow]混淆,實際上它們也有類似之處。前者表示這個包的發送方暫時沒辦法再發送數據了,後者表示這個包的發送方暫時沒辦法再接收數據了,也就是說二者都意味着傳輸暫停,都必須引發重視。
10.[TCP segment of a reassembled PDU]
11.[Continuation to #]
圖11
仔細對比圖10和圖11,你會發現Read Response在圖10中被算在了48號包頭上,而在圖11中被算到了39號包頭上。這樣會帶來一個詭異的結果:圖10的讀響應時間爲2.528毫秒(38號包和48號包的時間差),而圖11的讀響應時間爲2.476毫秒(38號包和39號包的時間差)。究竟哪一個算正確呢?這個問題很難回答,若是在意的是實際的總性能,那就看前者;若是想忽略TCP/IP協議的損耗,單看服務器的響應速度,那就看後者。在某些特殊狀況下,這二者相差很是大,因此必須搞清楚。
12.[Time-to-live exceeded (Fragment reassembly time exceeded)]
ICMP的報錯有好多種,大都不難理解,因此咱們只舉其中的一種爲例。 [Fragment reassembly time exceeded]表示這個包的發送方以前收到了一些分片,可是因爲某些緣由遲遲沒法組裝起來。好比在圖12中,因爲上海發往北京的一些包被分片傳輸,且有一部分在路上丟失了,因此北京方沒法組裝起來,便只好用這個ICMP報錯告知上海方。
圖12