天天看點

簡述TCP三向交握和四次揮手流程前言三次握手四次揮手總結

文章目錄

  • 前言
  • 三次握手
  • 四次揮手
  • 總結

前言

關于TCP的連接配接過程,很多從事程式開發的小夥伴應該都聽過三次握手,可這三次握手的細節還是有很多人不太清楚的,特别是有些參數記不清楚,我也經常弄錯,是以我根據自己的了解畫了兩張圖,将TCP連接配接和斷開的流程簡單記錄一下,以友善後續查找複習之用。

三次握手

簡述TCP三向交握和四次揮手流程前言三次握手四次揮手總結

初始狀态:用戶端A和伺服器B均處于

CLOSED

狀态,然後伺服器B建立socket,調用監聽接口使得伺服器處于

LISTEN

狀态,等待用戶端連接配接。(後續内容用A,B簡稱代替)

  1. A首先向B發起連接配接,這時TCP頭部中的SYN辨別位值為1,然後標明一個初始序号

    seq=x

    (一般是随機的),消息發送後,A進入

    SYN_SENT

    狀态,

    SYN=1

    的封包段不能攜帶資料,但要消耗一個序号。
  2. B收到A的連接配接請求後,同意建立連接配接,向A發送确認資料,這時TCP頭部中的SYN和ACK辨別位值均為1,确認序号為

    ack=x+1

    ,然後標明自己的初始序号

    seq=y

    (一般是随機的),确認消息發送後,B進入

    SYN_RCVD

    狀态,與連接配接消息一樣,這條消息也不能攜帶資料,同時消耗一個序号。
  3. A收到B的确認消息後,需要給B回複确認資料,這時TCP頭部中的ACK辨別位值為1,确認序号是

    ack=y+1

    ,自己的序号在連接配接請求的序号上加1,也就是

    seq=x+1

    ,此時A進入

    ESTABLISHED

    狀态,當B收到A的确認回複後,B也進入

    ESTABLISHED

    狀态,至此TCP成功建立連接配接,A和B之間就可以通過這個連接配接互相發送資料了。

四次揮手

簡述TCP三向交握和四次揮手流程前言三次握手四次揮手總結

初始狀态:用戶端A和伺服器B之間已經建立了TCP連接配接,并且資料發送完成,打算斷開連接配接,此時用戶端A和伺服器B是等價的,雙方都可以發送斷開請求,下面以用戶端A主動發起斷開請求為例。(後續内容用A,B簡稱代替)

  1. A首先向B發送斷開連接配接消息,這時TCP頭部中的FIN辨別位值為1,序号是

    seq=m

    ,m為A前面正常發送資料最後一個位元組序号加1得到的,消息發送後A進入

    FNI_WAIT_1

    狀态,

    FIN=1

    的封包段不能攜帶資料,但要消耗一個序号。
  2. B收到A的斷開連接配接請求需要發出确認消息,這時TCP頭部中的ACK辨別位值為1,确認号為

    ack=m+1

    ,而自己的序号為

    seq=n

    ,n為B前面正常發送資料最後一個位元組序号加1得到的,然後B進入

    CLOSE_WAIT

    狀态,此時就關閉了A到B的連接配接,A無法再給B發資料,但是B仍然可以給A發資料(此處存疑),同時B端通知上方應用層,處理完成後被動關閉連接配接。然後A收到B的确認資訊後,就進入了

    FIN_WAIT_2

    狀态。
  3. B端應用層處理完資料後,通知關閉連接配接,B向A發送關閉連接配接的消息,這時TCP頭部中的FIN和ACK辨別位值均為1,确認号

    ack=m+1

    ,自己的序号為

    seq=k

    ,(B發出确認消息後有發送了一段資料,此處存疑),消息發送後B進入

    LAST_ACK

    狀态。
  4. A收到B的斷開連接配接的消息後,需要發送确認消息,這是這時TCP頭部中的ACK辨別位值為1,确認号

    ack=k+1

    ,序号為

    m+1

    (因為A向B發送斷開連接配接的消息時消耗了一個消息号),然後A進入

    TIME_WAIT

    狀态,若等待時間經過2MSL後,沒有收到B的重傳請求,則表明B收到了自己的确認,A進入

    CLOSED

    狀态,B收到A的确認消息後則直接進入

    CLOSED

    狀态。至此TCP成功斷開連接配接。

總結

  1. 關于三次握手,參考了很多資料說伺服器是被動打開連接配接,對此有些不解,希望知道的朋友給出提示和建議。
  2. 關于四次揮手,在我的叙述中有兩處存疑,就是B收到的A的主動斷開請求後,進入

    CLOSE_WAIT

    狀态,是否還能發送資料到A,參考了一些資料說A不能發資料給B,但是B能發資料給A,并且A也可以接收,但是無論我在Windows環境測試還是Linux環境下測試這種狀态A都無法收到B的資料,不知道我是不是了解錯了,希望明白原理的小夥伴能解答一下。
  3. 在四次揮手的最後階段,有一個等待時間2MSL,這個不是一個時間機關,而是一個表明時間段的名詞,這段等待時間就是為了在B沒收到确認消息時,接收B的重傳請求的,如果不等待這一段時間直接進入

    CLOSED

    狀态,那麼B未收到A的确認消息就會發送重傳請求,而此時A已經關閉,就不會再給B重傳了,其中MSL的是Maximum Segment Lifetime英文的縮寫,可簡單譯為“封包最大生存時間”,也就是說如果B沒有收到确認資訊,那麼在2MSL這段時間内很大機率就會發送重傳請求,并且被A收到,RFC 793中規定MSL為2分鐘,實際應用中常用的是30秒,1分鐘和2分鐘等。
  4. 在連接配接和斷開的過程都有提到

    ACK

    ack

    ,這一點要注意區分,大寫的

    ACK

    代表TCP頭部中6個辨別位之一,是表明這是個确認封包,而小寫的

    ack

    拜師确認序号,表明對方發來的資料到

    ack

    這個序号前的都已經收到了。

繼續閱讀