從大學有網絡課程起就知道有三次握手這回事,但對其中到底發生了什麼一直懵懵懂懂,今天打算藉助 Wireshark 這一著名的網絡數據包分析軟件重現一下握手過程。服務器
字段對應關係及釋義:網絡
在 Wireshark 中左邊實線(圖中21 - 2八、133 - 13四、427 - 428)連起來的一段能夠視爲爲同一次會話內發生的各個階段,不過圖中的是簡單順利的一次會話過程,沒有失敗重傳、分片傳輸等其餘狀況。tcp
另外:測試
文中7001爲服務器所在端口號。spa
第21個網絡包:客戶端發送第一個網絡包,在頭部寫入發送方、接收方端口號(用來找到目標套接字),設置客戶端初始序號爲0, SYN 控制位爲1,等待服務器確認,因爲此時客戶端還未接收過網絡包,因此 ACK 控制位爲0。code
第22個網絡包:服務器收到網絡包,一樣返回一個響應包,在TCP頭部寫入發送方、接收方端口號(此時對服務器來講是發送方)、服務端初始序號0, SYN 控制位1,另外還要設置 ACK 控制位爲1,表示已收到有效網絡包;除此以外能夠注意到 ACK號 也被置爲1了,就是上文提到的 SYN 控制位佔用的一個確認號。blog
第23個網絡包:客戶端收到網絡包,發現 SYN 控制位爲1,表示鏈接成功,同時發送一個 ACK 控制位設置爲1的網絡包給服務器,告知服務器剛纔的響應包已收到,這裏能夠發現序號變爲1,那是由於服務器返回的響應包中確認了客戶端發送的 SYN 控制位爲1,因此序號須要 +1;在服務器收到後三次握手就所有完成了,後面就能夠開始收發數據了。ip
後面的[TCP Window Update]是用來窗口更新的,這裏不作闡述。get
第25個網絡包:客戶端發起了一個 HTTP 頁面請求,TCP詳細信息以下:it
能夠看到這個網絡包已經不僅僅是控制信息的傳輸,開始包含數據,而且數據佔用621字節,同時 Wireshark 已經機智在計算下一個客戶端發送的包序號了, 621…...
而後服務器告知客戶端已收到該請求,響應第26個網絡包:
ACK號 = 前一次的 ACK號 + 本次收到的數據字節數 = 1 + 620 = 621;
序號保持不變,由於本次只是發送控制信息,並無發送數據。
Tips:在 WireShark 選中某個網絡包,如上圖No.26,結果No.25前面出現了一個對勾,能夠看做是No.26對No.25的消息確認。
在第27個網絡包中,服務器針對HTTP請求返回頁面內容:
能夠看到這個網絡包的數據大小爲4152字節,這以後理論上在客戶端應該會返回一個 ACK號 爲4153的確認包。
在第28個網絡包中,序號就如前面 Wireshark 計算的等於621,ACK號的計算和第26個網絡包類似,再也不贅述。
在結束最後一個網絡包的傳輸後,再過一段時間(上圖中大概5秒),如沒有數據往來Web服務器就會關閉鏈接,至於爲何要延時,大概是爲了短期內若是有後續數據交換,能夠減小從新建立套接字創建鏈接的開銷吧。
服務器生成包含斷連控制信息 FIN 的TCP頭部發送給客戶端。
客戶端告知服務器已收到斷連信號 FIN , 由於收到的 FIN 佔用一個確認號,因此回覆的 ACK號 = 4153 + 1 = 4154。
客戶端在讀取全部緩衝區的數據後,也會向服務器發送一個 FIN 爲1的網絡包。
服務器同理返回 ACK號 確認收到 FIN 控制信息。
這就是斷連操做的四次握手。
測試數據下載連接,過濾規則 tcp.port == 7001
。
該文章首發於個人我的站點