1. 程式人生 > >TCP 連線的建立和終止

TCP 連線的建立和終止

TCP連線的建立

    三次握手

image

  1. 伺服器端準備好接收外來的連結,通過該socket、bind、listen3個函式完成,為被動開啟
  2. 客戶端通過connect函式主動建立連線,通過傳送一個SYN(帶序號)
  3. 伺服器確認(ACK)客戶的SYN,確認序號為服務SYN的序號加1,同時傳送一個SYN(帶序號)
  4. 客戶端確認(ACK)服務的SYn,確認序號為服務SYN的序號加1.

   如上就是我們通常所說的三次握手

TCP連線的終止

     四次握手

  image

  1. Client呼叫close主動關閉(通常是Client,也可以是server)。傳送一個FIN(帶序號)。進入FI_WAIT1狀態
  2. 接收到FIN的對端執行被動關閉。傳送ACK確認。然後進入CLOSE_WAIT。對端接收到ACK進入FIN_WAIT_2。此時為單方向關閉。
  3. 對端呼叫close執關閉。傳送FIN(帶序號)。進入LAST_ACK狀態。
  4. 接收到FIN的client傳送ACK確認,進入TIME_WAIT狀態。
  5. Server接收到ACK之後進入CLOSED狀態。完成連線的關閉。

如上為連線關閉的四次握手。

CLOSE_WAIT

    Server接收到Client的FIN回覆ACK之後進入CLOSE_WAIT狀態。此時Client到Server的連線關閉。Client不能向Server傳送資料。而此時Server仍可以向Client傳送資料。

即此時為單向的連線關閉。需要Server也執行close關閉,才能轉入之後的狀態。

   有時我們發現server有大量的close_wait,原因就是對方關閉了連線,而這邊由於忙於讀寫或其他原因,沒有執行關閉。

TIME_WAIT

    Client端接收到Server的FIN傳送相應的ACK之後,進入TIME_WAIT狀態。該狀態的持續時間最長為MSL(maximum segment lifetime)的兩倍,即2MSL。

RFC1122的建議值為2分鐘,而Berkeley的傳統實現為30秒。所以其持續時間在1分鐘到4分鐘之間。

    其存在是為了保證最後的ACK可以成功達到。否則會在MSL之後,Server重新發送FIN,從而觸發其重新發送ACK。最長為2MSL的時間。這個是最主要的理由。

    還有一個理由是允許老的重複segment在網路中消逝:

     考慮如下一個場景,在A的埠port1和B的埠port2建立了TCP連線,然後關閉了連線。為了保證過一段時間,我們還可以在A的埠port1和B的埠port2之間可以

建立連線。我們應該避免之前的在該連線上的老的分組再出現。為做到這一點,TCP不給處於TIME_WAIT狀態的連線發起新的連線。TIME_WAIT的狀態持續時間為2MSL,

這樣每個方向上的資料的最大存活時間為MSL。這樣保證成功建立一個TCP連線時,來自該連線的先前的老的重複分組都已經在網路中消逝了。