天天看點

TCP三向交握和Time-Wait狀态

  • 第一次握手:建立連接配接時,用戶端發送

    syn

    包和一個随機序列号

    seq=x

    到伺服器,并進入

    SYN_SEND

    狀态,等待伺服器進行确認。(

    syn

    ,同 步序列編号)。
  • 第二次握手,伺服器收到

    syn

    包,必須确認客戶的

    SYN

    ,然後伺服器發送一個

    ACK=1, SYN=1, seq=y

    的随機數和

    ack=x+1

    的确認數的包發送回去。
  • 第三次握手是用戶端收到伺服器端的

    SYN+ACK

    包,然後向伺服器端發送确認包

    ack=y+1, seq=x+1, ACK=1

    ,用戶端和伺服器端進入

    ESTABLISHED

    狀态,完成三次握手。具體圖示如下(

    ACK

    表示首部中的

    ACK

    位置1,

    ack

    表示首部中确認序号字段的值):
TCP三向交握和Time-Wait狀态
TCP三向交握和Time-Wait狀态

這裡多說一點,既然提到了連接配接時的三次握手,就順便把斷開連接配接時的四次揮手也複習一下。

  • 首先用戶端主動發送

    Fin=1,seq=u

    ,它等于前面已傳 送過去的最後一個位元組的序号加1.這時

    A

    進入

    FIN-WAIT-1

    狀态,等待

    B

    的确認。
  • B

    收到連接配接後立即發出确認,确認号是

    ack=u+1

    ,而這個封包段 自己的序号是

    v

    ,等于

    B

    前面已傳送過的資料的最後一個位元組的序号加1.然後

    B

    即進入

    CLOSE-WAIT

    狀态。因而

    A

    B

    的這個連結現在已經斷開了,這時 的

    TCP

    連接配接處于半關閉狀态,即

    A

    已經沒有資料需要發送了。但

    B

    若發送資料,

    A

    還是要接受的。

    A

    收到來自

    B

    的确認之後就進入了

    FIN-WAIT-2

    狀态等 待

    B

    發出連接配接釋放封包段。
  • B

    已經沒有要向

    A

    發送資料,其應用程序就通知

    TCP

    釋放連接配接。這時

    B

    發出的連接配接釋放封包段必須使用

    FIN=1

    .現在假定

    B

    的序 号為

    w

    B

    還必須重複上次已發送過的确認号

    ack=u+1

    .這時

    B

    就進入了

    LAST-ACK

    狀态,等待

    A

    确認。
  • A

    在收到

    B

    的連接配接釋放之後必須對此發出确 認。在确認号中把

    ACK

    置1,确認号

    ack=w+1

    ,而自己的序号是

    seq=u+1

    。接着

    A

    進入

    TIME-WAIT

    狀态。為了保證

    B

    可以收到确認釋放封包段。如下圖:
TCP三向交握和Time-Wait狀态

是不是所有執行主動關閉的

socket

都會進入

TIME_WAIT

狀态呢?

有沒有什麼情況使主動關閉的

socket

直接進入

CLOSED

狀态呢?

主動關閉的一方在發送最後一個

ack

就會進入

TIME_WAIT

狀态 停留

2MSL

max segment lifetime

)時間

這個是

TCP/IP

必不可少的,也就是“解決”不了的。也就是

TCP/IP

設計者本來是這麼設計的

主要有兩個原因:

  1. 防止上一次連接配接中的包,迷路後重新出現,影響新連接配接

    (經過

    2MSL

    ,上一次連接配接中所有的重複包都會消失)
  2. 可靠的關閉

    TCP

    連接配接

    在主動關閉方發送的最後一個

    ack(fin)

    ,有可能丢失,這時被動方會重新發

    fin

    , 如果這時主動方處于

    CLOSED

    狀态 ,就會響應

    rst

    而不是

    ack

    。是以

    主動方要處于

    TIME_WAIT

    狀态,而不能是

    CLOSED