天天看點

通過tcpdump+wireshark來抓包分析TCP長連接配接和短連接配接的差別

最近開發中遇到以下:需要用戶端建立一個連結,然後伺服器端持有這個連結,當有時間變換(如任務的狀态改變),需要後端将事件推送給任務對應的責任人。因為部落客之前也研究過WebSocket,開發了個簡單的聊天室,但是這次這次應用到實際,我就在想TCP的這個長連接配接在不發生異常的情況下可以維持多久?在思考這個問題時,我就在想Http建立的TCP短連接配接,是什麼時候斷開連接配接的?基于這個問題,我就寫了個簡單的測試用例,通過tcpdump來抓包,對長連接配接和短連接配接進行對比分析。

​ 下面我們來簡單的介紹下長連接配接和短連接配接的概念。

​ 首先是TCP,三次握手建立連接配接,四次揮手釋放連接配接,示意圖如下:

通過tcpdump+wireshark來抓包分析TCP長連接配接和短連接配接的差別

​ 短連接配接就如上圖所示,資料傳輸完成後,一般由用戶端發起釋放連接配接的信号,也可以看到,短連接配接是進行一次請求,請求結束後斷開連接配接,那就回到上面令部落客疑惑的問題了,建立連接配接我們都知道,Http請求到達伺服器,就會立刻建立TCP連接配接,那是什麼時候斷開的呢?是伺服器return了結果後立刻結束麼,還是别的情況,别急,後面我們會來給大家講解。

​ 長連接配接,和短連接配接最簡單最直接的差別就是,他是為了伺服器和用戶端間的一個頻繁的互動,之前的浏覽器端定時的ajax輪詢會消耗大量的資源,現在已經很少有人使用了;另一個,長連接配接比短連接配接更大的一個優勢就是,伺服器端可以維護和用戶端建立的這個TCP通信的channel,這樣就可以讓伺服器主動的給用戶端發送資料,也等同于實作了全雙工通信,這個也是相比ajax輪詢更大的一個優勢,可以實作事件的實時通知。

基于上面所講的,我們來分析下長連接配接和短連接配接的優缺點:

  1. 長連接配接可以省去較多的TCP建立和關閉的操作,減少浪費,節約時間。對于頻繁請求資源的客戶來說,較适用長連接配接;
  2. 長連接配接如果不主動關閉,這個連接配接會長久的存在,并且如果長連接配接濫用,或者不加任何限制,會導緻連接配接數過多,會對伺服器的産生較大的壓力,是以長連接配接在使用時要慎用,做好評估和限制;
  3. 短連接配接對于伺服器來說管理較為簡單,存在的連接配接都是有用的連接配接,不需要額外的控制手段。但如果客戶請求頻繁,将在TCP的建立和關閉操作上浪費時間和帶寬。

​ 下面,我們就開始使用tcpdump來進行抓包來分析上面讓我們疑惑的兩個問題,首先,我們啟動服務端,長連接配接就是我們使用的WebSocket,短連接配接就是一個簡單的無業務邏輯的一個接口,

​ 在電腦上啟動tcpdump,指令如下,其中-w指定抓到的包的輸入路徑,如果沒有-w的話,會将包輸出到shell視窗:

sudo tcpdump -i lo0 -w /tmp/tcpdump/1.pcap port 8080
           

tcpdump指令的詳解大家可以參考這篇部落格:https://www.jianshu.com/p/b281964a8459

​ 本文為了更好的分析,将日志輸出到檔案,并使用wireshark軟體進行分析,資料包如下:

通過tcpdump+wireshark來抓包分析TCP長連接配接和短連接配接的差別

​ 從中我們可以看到,紅框中的為TCP連接配接建立的過程,紅色箭頭是建立WebSocket的請求,後面我們可以看到,資料反而發送就是TCP和WebSocket協定了,後面用戶端和服務端之間的資料發送就無須建立TCP連接配接了,這和我們預料的是一緻。

​ 但是困擾我們的一個問題:長連接配接在不發生異常的情況下可以維持多久?經過部落客的測試,4個小時是沒有任何問題的,具體多久就沒有繼續測試啦。。。而且,這個連接配接的保持應該有用戶端來進行,可以定時的檢查連接配接的狀态,如果連結斷開,可以重建立立連接配接,這樣可以保證連接配接的暢通,事件可以及時的有服務端推送到用戶端。

​ 下面我們來分析短連接配接,大家也也在思考一下困擾我們的問題:TCP短連接配接是什麼時候斷開的?結果可能和你預期的不太一樣,下面我們一起來看下:

​ 接口代碼如下:

@GetMapping("/create")
public String onCreate(){
    log.info("---------1111");
    return "OK";
}
           

​ 下面就是直接在浏覽器上輸入url,按下Enter鍵,并請求五次,每次的時間間隔為3s左右,wireshark分析得到的資料包如下:

通過tcpdump+wireshark來抓包分析TCP長連接配接和短連接配接的差別

由上圖我們可以看到,第一次調用接口時,建立了TCP連接配接,但是之後的每隔三秒的再次調用,是沒有重新建立TCP連接配接的,而是使用了之前已經建立好的連接配接,最後,在經過一段時間後,TCP斷開連接配接,因為wireshark中沒有時間,我們截取原始的資料包來展示TCP斷開連接配接的時間,

通過tcpdump+wireshark來抓包分析TCP長連接配接和短連接配接的差別

上圖是一次Http請求的所有封包,也是一次TCP連接配接的建立和斷開,從中我們可以看到,連接配接的建立和資料的發送很快就結束了,但是連接配接的斷開時在資料發送結束差不多45s開始的,由用戶端發送,ack 116,伺服器端真正斷開連接配接是在約一分鐘後。

​ 是不是和你預料的結果不太一緻呢?但是為什麼會導緻這個結果呢,大家看下面這張截圖:

通過tcpdump+wireshark來抓包分析TCP長連接配接和短連接配接的差別

之前,在http/1.0中,一個伺服器發送完http響應後,會斷開TCP連接配接。但是這樣每次請求都會重建立立和斷開TCP連接配接,開銷太大。是以雖然标準中沒有設定,某些伺服器對Connection:keep-alive的Header進行了支援。意思是說,完成這個HTTP請求後,不要斷開HTTP請求使用的TCP連接配接。這樣的好處是連接配接可以被重複使用,之後發送HTTP請求的時候就不用再重建立立TCP連接配接了。這也符合我們剛才截圖中的結果,這樣,如果我們頻繁的請求,Http短連接配接也是可以滿足需求的,可見在我們開發中,有很多問題都有人為我們考慮到了。