回覆列表
  • 1 # 使用者804386860247

    TIME_WAIT狀態

    TCP要保證在所有可能的情況下使得所有的資料都能夠正確被投遞。

    當關閉一個 socket 連線時,主動關閉一端的 socket 將進入TIME_WAIT狀態,而被動關閉一方則轉入CLOSED狀態。

    見圖解。

    當一個socket關閉的時候,是透過兩端互發資訊的四次握手過程完成的,當一端呼叫close()時,就說明本端沒有資料再要傳送了。這好似看來在握手完成以後,socket就都應該處於關閉CLOSED狀態了。但這有兩個問題,

    第一:我們沒有任何機制保證最後的一個ACK能夠正常送達

    第二:網路上仍然有可能有殘餘的資料包(wandering duplicates,或老的重複資料包),我們也必須能夠正常處理。

    假設最後一個ACK丟失了,伺服器會重發它傳送的最後一個FIN,所以客戶端必須維持一個狀態資訊,以便能夠重發ACK;如果不維持這種狀態,客戶端在接收到FIN後將會響應一個RST,伺服器端接收到RST後會認為這是一個錯誤。如果TCP協議能夠正常完成必要的操作而終止雙方的資料流傳輸,就必須完全正確的傳輸四次握手的四個節,不能有任何的丟失。這就是為什麼socket在關閉後,仍然處於 TIME_WAIT狀態,因為他要等待以便重發ACK。

    如果目前連線的通訊雙方都已經呼叫了close(),假定雙方都到達CLOSED狀態,而沒有TIME_WAIT狀態時,就會出現如下的情況。現在有一個新的連線被建立起來,使用的IP地址與埠與先前的完全相同,後建立的連線又稱作是原先連線的一個化身。還假定原先的連線中有資料報殘存於網路之中,這樣新的連線收到的資料報中有可能是先前連線的資料報。為了防止這一點,TCP不允許從處於TIME_WAIT狀態的socket建立一個連線。處於TIME_WAIT狀態的socket在等待兩倍的MSL時間以後(之所以是兩倍的MSL,是由於MSL是一個數據報在網路中單向發出到認定丟失的時間,一個數據報有可能在傳送圖中或是其響應過程中成為殘餘資料報,確認一個數據報及其響應的丟棄的需要兩倍的MSL),將會轉變為CLOSED狀態。這就意味著,一個成功建立的連線,必然使得先前網路中殘餘的資料報都丟失了。

    由於TIME_WAIT狀態所帶來的相關問題,我們可以透過設定SO_LINGER標誌來避免socket進入TIME_WAIT狀態,這可以透過傳送RST而取代正常的TCP四次握手的終止方式。但這並不是一個很好的主意,TIME_WAIT對於我們來說往往是有利的。

  • 中秋節和大豐收的關聯?
  • 幼兒園《爸爸媽媽聽我說》元旦主持詞要怎麼講,請大家幫幫忙啊?