1. 程式人生 > >客戶端多次RST以及不同場景下的RST報文的差異

客戶端多次RST以及不同場景下的RST報文的差異

      在某個TCP互動過程中,我們發現在互動的後期,客戶端多次向伺服器端傳送RST報文,如下圖所示:

點選檢視原圖

        我們首先來看客戶端發出的第一個RST報文的解碼:

點選檢視原圖

       RST與ACK標誌位都置一了,並且具有ACK number,非常明顯,這個報文在釋放TCP連線的同時,完成了對前面已接收報文的確認。

       我們再來看看客戶端發出的後續RST報文的解碼:

點選檢視原圖

       我們可以看到,這些後續的RST報文僅Reset位置一,ACK位未置一,在這種情況下,該報文的ACK確認號應該為0,但是我們留意到在這個報文中,其ACK確認號與序列號是一致的。

       這是為什麼呢?

       因為ACK位未置一,ACK確認號也就失去了意義,因此,不論ACK確認號是什麼值都不會對接收端產生影響,因此大部分的系統都會將ACK確認號設定為0,之所以在這個報文中出現ACK確認號非0而是與序列號一致的情況,個人認為應該是該主機端系統的處理機制與大部分系統不一樣導致的。

       另外,我們也看到了wireshark的專家系統在此處給出了提示,由此可見wireshark在傳輸層的專家系統的強大之處。

       為什麼前後RST報文會出現這種差異?

       原因為第一個RST報文是異常釋放TCP連線的,在端系統傳送RST報文之前,這個TCP連線尚在端系統的連線表中,因此其ACK位置一併且具有ACK確認號。而客戶端後續收到DATA報文,因其連線表中已經沒有相關資訊與之對應,此時客戶端傳送的RST報文ACK位無需置一。

       也許有朋友會問:伺服器端為什麼在收到客戶端的RST報文後,還繼續給客戶端傳送報文呢?

       原因只有一個,那就是TCP成塊資料流。伺服器端一次性向客戶端傳送數個數據塊,在客戶端發出第一個RST報文之後,後續的報文已經在網路中傳輸了,並陸續達到客戶端。

       其互動過程大致如下:

點選檢視原圖