前言:
想起了第一次聽說“三次握手”概念的時候,那時候剛到北京,朋友傲嬌的跟我講,我花了兩天我終于搞懂了三次握手,當時對網路一無所知的我,還以為是啥新的禮儀方式,心中感嘆,帝都人民的熱情,握手還要三次,說到半途才搞清楚,原來是TCP創建連接的禮儀,后面空閑的時候,經常從網上找些找些資料,接觸“三次握手”,用網友經典的打電話例子,淺淺的理解,時間推移,由淺入深,大概所有人都跟我一開始有同樣以下的這個問題:
提問:
為啥TCP建立連接需要進行三次握手?
三次握手
回答問題前,我還是想老生常談的自己講解下什么是三次握手,
何為三次握手?
比起語言敘述,有時候圖會先的更具體和簡單易懂:

圖文講解
講解SYN和ACK:
客戶端和服務端進行三次握手時除了必要的傳輸資料,還會有標志位資訊,三次握手時,SYN和ACK就是標志位,標志位的作用是,讓服務端/客戶端根據不同的標志位來確定當前的資料進行對應處理,
比如當服務端發現標志位是SYN=1,就會知道當前的資料是進行第一次握手的請求,然后就會按照第一次握手的規則來處理資訊,同樣第二次握手時客戶端根據SYN=1,ACK=1標志位就會確定是來自服務端的第二次握手的應答請求,然后進行相應的處理,
第一次握手:
由客戶端發起,當客戶端發起SYN請求后,將客戶端狀置為SYN_SENT狀態,等待服務端確認,此時請求資訊中標志位SYN=1,序列Seq=n,
第二次握手:
服務端接收到SYN請求,將Seq在原來值n得基礎上加1,賦值Ack=n+1,并且服務端再生成一個序列號m,賦值Aeq=m,服務端應答請求,標志位SYN=1、ACK=1,序列資訊Seq=m、Ack=n+1,同時將服務端狀態置為SYN_RCVD,等待客戶端確認,
第三次握手:
客戶端接收到訊息,根據標志位SYN=1、ACK=1決議資料,確認Ack=n+1,然后序列賦值Ack=m+1,客戶端向服務端發起ACK=1請求,客戶端接收到請求,根據標志位ACK=1,校驗序列Ack=m+1,校驗無誤后,將客戶端和服務端狀態置為ESTABLISHED,建立連接,就可以進行正常的通訊了,
總結:
我們發現所謂三次握手,不過就是客戶端和服務端,通過發送三次資料包,來確認連接建立,
我們又知道,TCP的是一個雙工連接,即是一個雙向連接,就是服務端和客戶端都有資料的發送和接收能力,
這就很好的解答了,為何TCP建立連接需要三次握手:
客戶端和服務端都必須確認資料是否準確的發送和接收,而在三次握手中序列Seq和Ack的發送和接收,就代表著資料的準確發送和接收,
假如進行兩次握手,只有客戶端校驗了自己生成的序列號,確認了自己的發送和接收能力,很明顯是不夠的,那為啥不能是四次?我只能說,任何事情三次能解決的事,沒必要四次,更何況是作為程式員去解決問題,
用一個資料庫連接來驗證三次握手:
準備:wireshark(抓包工具),navicat(資料庫可視化工具),mysql
說明:mysql的連接是一個TCP連接
1.打開wireshark

2.打開navicat

此時并沒有創建連接,
3.wireshark編輯捕獲器,監聽3306埠(mysql連接埠)

4.點擊開始

由于3306埠暫無通信所以為空
5.點擊navicat其中一個資料庫連接

6.我們發現3306埠有資料包
我們先簡單看下前三No1、No2、No3

注意標志位和Seq是不是有些似曾相識,和我們上面上述的三次握手是不是有些相似?
詳細看下:
第一個包No1:

下方紅色框框SYN=1 ,說明這是第一次握手,上方黃色框為客戶端生成的序列號Seq=0,
第二個包No2:

下方紅色框框SYN=1 和ACK=1,說明這是第二次握手,上方黃色框為服務端生成序列號Seq=0和應答序列號Ack=1(即Ack=客戶端值為0的Seq+1),
第三個包No3:

下方紅色框框ACK=1,說明這是第三次握手,上方黃色框為客戶端應答序列號Ack=1(即Ack=服務端生成的seq+1),
總計:三次握手雙方的序列號都校驗無誤,故三次握手成功,建立連接,所以有了下方的No4,5,6等等的資料傳輸
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/290046.html
標籤:其他
