如果對tcp還不瞭解的,可以看看計算機網絡基礎簡單瞭解一下;
如果對tcp的深入感興趣,看了上一篇還不過癮的可以看吊打面試官!近 40 張圖解被問千百遍的 TCP 三次握手和四次揮手面試題
好了,如果看回來了我們來進入正題,首先了解一下wireshark
抓包工具wireshark
首先去官網下載對應安裝包https://www.wireshark.org/download.html
window安裝下一步下一步、默認就行,其中有一個統計usb的包是否安裝,可以不裝
啓動服務,第一步選擇網卡
常用知識
不同的協議有不同的着色規則;點擊 視圖-->着色規則 查看
過濾欄包含:保存,停止、重新捕獲、切換網卡等等
數據過濾
通過數據過濾,來查看我們的請求的具體執行情況
ip.addr == 216.58.200.42 根據ip篩選
ip.addr == 10.200.60.88 and http 根據ip和協議篩選,好像還有http2
看見HTTP協議
首先,從之前的兩篇TCP博客拿一些TCP協議的基本概念,方便後面的理解
準備一個簡單的http接口如圖:
請求地址 http://127.0.0.1:11003/demo/servicea/person/123 ,響應很簡單
使用postman來請求,開啓wireshark的抓包,然後通過ip.addr == 10.200.60.88過濾指定請求
HTTP請求分析
## tcp摘要信息
54251 → 11003 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
54251 → 11003 端口號:源端口--->目標端口
[SYN] client-->server [SYN、ACK] server響應ACK [ACK] 客戶端確認ack、連接建立
Seq : 消息序列號、【基本上針對的ack = seq+1】
Win: TCP 窗口大小;最大65535=64kb
Len: 消息長度;len = TCP數據長度 = IP總長度-IP首部長度-TCP首部長度
Mss: 最大報文段長度;規定的最大報文長度;
Ws: 窗口縮放調整因子;ws * win = 時間窗口長度
SACK_PERM : SACK選項,這裏等於1表示開啓 SACK。
明顯看到133-134-135是tcp的三次握手;然後136是http請求:client-->server
137是針對136的http的ack確認,140的[PSH,ACK]是針對136的http消息體響應
141是服務端對客戶端的響應server-->client;142是客戶端對服務端的確認。
http1.1默認開啓keepAlive;後面就是keepalive;
keepalive使用心跳檢查,client-->server ;服務端響應ack;
間隔固定的時間去重複這個過程;
TCP的[PSH,ACK]
網上對TCP segment of a reassembled PDU解釋不清不楚;
使用postman在body放無效數據來觀察
對面上面兩張 wireshark抓包的圖:可以看到客戶端包含數據時候,會發送[PSH,ACK];沒有數據的情況直接使用http請求
使用google瀏覽器試一試,發現執行了兩次tcp三次握手,有博客說爲了google可用性設計、供參考;
一次MQTT協議異常的排查
對mqtt不瞭解的可以看看MQTT和協議筆記;
mqtt是一個工業環境下的mq協議,需要mqtt server端,一端發消息,一端收消息;
某個項目中使用mqtt協議,同事排查發現問題,發現mqtt server掛了重啓以後,客戶端會一直重連;但是一直重連不上
表現爲:連接成功--->訂閱----阻塞---訂閱成功---斷開連接 ---->重連成功---->訂閱 一直循環
由於不方便貼源碼,直接說造成這次後果的原因
1、重連以後會重新訂閱topic、訂閱調用阻塞的await方法導致無法處理訂閱的ack響應,阻塞10秒
2、mqtt client有個定時器發送消息失敗(未接到響應ack)會重新發送消息,默認10秒每次加5秒去重發消息;
但是重發的消息是針對PUBLISH的消息,導致重發訂閱消息協議錯誤,服務端斷開連接
## mqtt消息類型回顧
CONNECT – 連接服務端
CONNACK – 確認連接請求
PUBLISH – 發佈消息
PUBACK –發佈確認
PUBREC – 發佈收到(QoS 2,第一步)
PUBREL – 發佈釋放(QoS 2,第二步)
PUBCOMP – 發佈完成(QoS 2,第三步)
SUBACK – 訂閱確認
UNSUBSCRIBE –取消訂閱
UNSUBACK – 取消訂閱確認
PINGREQ – 心跳請求
PINGRESP – 心跳響應
DISCONNECT –斷開連接
mqtt server mosquitto報錯: Client netty-mqtt/08elI9Go disconnected due to protocol error
再此開啓wireshark的抓包,信息如下
簡單分析:
118~120 tcp三次握手
121~124 mqtt的連接和確認
135~138 mqtt的訂閱確認,topic是mqtt-test
147~150 tcp的四次揮手
將Mqtt服務關閉,客戶端有重連機制去重新連接服務端,發送tcp的syn;
[RST,ACK]服務端斷開連接;[TCP Retransmission] 客戶端重傳
服務端發送 tcp rst終止重連,TCP重傳一次;繼續這個過程
等服務端正常啓動,又進入上面的流程tcp三次握手,建立mqtt connect;
通過比對第一次正常訂閱,和第二次異常訂閱導致服務端關閉連接的信息;
mqtt 訂閱的消息頭,一個是82,一個是8a;協議重發出現問題;
最終確認訂閱消息重發了,重發的消息出現問題導致報錯協議錯誤,服務端主動斷開連接,問題得到定位。