TCP串連的狀態與關閉方式,及其對Server與Client的影響

來源:互聯網
上載者:User

1. TCP串連的狀態

  首先介紹一下TCP串連建立與關閉過程中的狀態。TCP串連過程是狀態的轉換,促使狀態發生轉換的因素包括使用者調用、特定資料包以及逾時等,具體狀態如下所示:

  • CLOSED:初始狀態,表示沒有任何串連。
  • LISTEN:Server端的某個Socket正在監聽來自遠方的TCP連接埠的串連請求。
  • SYN_SENT:發送串連請求後等待確認資訊。當用戶端Socket進行Connect串連時,會首先發送SYN包,隨即進入SYN_SENT狀態,然後等待Server端發送三向交握中的第2個包。
  • SYN_RECEIVED:收到一個串連請求後回送確認資訊和對等的串連請求,然後等待確認資訊。通常是建立TCP串連的三向交握過程中的一個中間狀態,表示Server端的Socket接收到來自Client的SYN包,並作出回應。
  • ESTABLISHED:表示串連已經建立,可以進行資料轉送。
  • FIN_WAIT_1:主動關閉串連的一方等待對方返回ACK包。若Socket在ESTABLISHED狀態下主動關閉串連並向對方發送FIN包(表示己方不再有資料需要發送),則進入FIN_WAIT_1狀態,等待對方返回ACK包,此後還能讀取資料,但不能發送資料。在正常情況下,無論對方處於何種狀態,都應該馬上返回ACK包,所以FIN_WAIT_1狀態一般很難見到。
  • FIN_WAIT_2:主動關閉串連的一方收到對方返回的ACK包後,等待對方發送FIN包。處於FIN_WAIT_1狀態下的Socket收到了對方返回的ACK包後,便進入FIN_WAIT_2狀態。由於FIN_WAIT_2狀態下的Socket需要等待對方發送的FIN包,所有常常可以看到。若在FIN_WAIT_1狀態下收到對方發送的同時帶有FIN和ACK的包時,則直接進入TIME_WAIT狀態,無須經過FIN_WAIT_2狀態。
  • TIME_WAIT:主動關閉串連的一方收到對方發送的FIN包後返回ACK包(表示對方也不再有資料需要發送,此後不能再讀取或發送資料),然後等待足夠長的時間(2MSL)以確保對方接收到ACK包(考慮到丟失ACK包的可能和迷路重複資料包的影響),最後回到CLOSED狀態,釋放網路資源。
  • CLOSE_WAIT:表示被動關閉串連的一方在等待關閉串連。當收到對方發送的FIN包後(表示對方不再有資料需要發送),相應的返回ACK包,然後進入CLOSE_WAIT狀態。在該狀態下,若己方還有資料未發送,則可以繼續向對方進行發送,但不能再讀取資料,直到資料發送完畢。
  • LAST_ACK:被動關閉串連的一方在CLOSE_WAIT狀態下完成資料的發送後便可向對方發送FIN包(表示己方不再有資料需要發送),然後等待對方返回ACK包。收到ACK包後便回到CLOSED狀態,釋放網路資源。
  • CLOSING:比較罕見的例外狀態。正常情況下,發送FIN包後應該先收到(或同時收到)對方的ACK包,再收到對方的FIN包,而CLOSING狀態表示發送FIN包後並沒有收到對方的ACK包,卻已收到了對方的FIN包。有兩種情況可能導致這種狀態:其一,如果雙方几乎在同時關閉串連,那麼就可能出現雙方同時發送FIN包的情況;其二,如果ACK包丟失而對方的FIN包很快發出,也會出現FIN先於ACK到達。

  TCP串連的狀態轉換如所示

2. TCP串連的關閉方式

  建立TCP串連需要三向交握,而關閉串連則需要四次握手,並且分為主動關閉和被動關閉。這是由於TCP串連是全雙工系統的,我關了你的串連,並不等於你關了我的串連,因此雙方都必須單獨進行關閉。當一方完成它的資料發送任務後可以發送FIN包來終止這個方向的串連,表明自己不再有資料需要發送;收到FIN包的那一方雖然不能再讀取資料,但仍能發送資料。以Client主動關閉串連為例:

  1. Client向Server發送FIN包,表示Client主動關閉串連,然後進入FIN_WAIT_1狀態,等待Server返回ACK包。此後Client不能再向Server發送資料,但能讀取資料。
  2. Server收到FIN包後向Client發送ACK包,然後進入CLOSE_WAIT狀態,此後Server不能再讀取資料,但可以繼續向Client發送資料。Client收到Server返回的ACK包後進入FIN_WAIT_2狀態,等待Server發送FIN包。
  3. Server完成資料的發送後,將FIN包發送給Client,然後進入LAST_ACK狀態,等待Client返回ACK包,此後Server既不能讀取資料,也不能發送資料。
  4. Client收到FIN包後向Server發送ACK包,然後進入TIME_WAIT狀態,接著等待足夠長的時間(2MSL)以確保Server接收到ACK包,最後回到CLOSED狀態,釋放網路資源。Server收到Client返回的ACK包後便回到CLOSED狀態,釋放網路資源。

  TCP串連的建立到關閉,需要經曆以下狀態遷移(假定Client發起串連,並主動關閉串連):

  • Client

  CLOSED -> SYN_SENT -> ESTABLISHED -> FIN_WAIT_1 -> FIN_WAIT_2 -> TIME_WAIT -> CLOSED

  • Server

  CLODES -> LISTEN -> SYN_RECEIVED -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED

3. 對Server與Client的影響

  在詳細瞭解TCP串連的狀態和關閉方式後,我們會發現TIME_WAIT狀態是一個坑爹的存在!主動關閉串連的一方在發送最後一個ACK包後,無論對方是否收到都會進入TIME_WAIT狀態,等待2MSL的時間,然後才能釋放網路資源。MSL就是Maximum Segment Lifetime(資料包的最大生命週期),是一個資料包能在互連網上生存的最長時間,若超過這個時間則該資料包將會消失在網路中。作業系統通常會將2MSL設為4分鐘,最低不少於30秒,因而TIME_WAIT狀態一般維持在30秒至4分鐘。這個是TCP/IP協議必不可少的,是TCP/IP設計者設計的,也就是無法解決的。TIME_WAIT狀態的存在主要有兩個原因:

  1. 可靠地實現TCP全雙工系統串連的終止。在關TCP閉串連時,最後的ACK包是由主動關閉方發出的,如果這個ACK包丟失,則被動關閉方將重發FIN包,因此主動方必須維護狀態資訊,以允許它重發這個ACK包。如果不維持這個狀態資訊,那麼主動方將回到CLOSED狀態,並對被動方重發的FIN包響應RST包,而被動關閉方將此包解釋成一個錯誤(在Java中會拋出connection reset的SocketException)。因而,要實現TCP全雙工系統串連的正常終止,必須能夠處理四次握手協議中任意一個包丟失的情況,主動關閉方必須維持狀態資訊進入TIME_WAIT狀態。
  2. 確保迷路重複資料包在網路中消失,防止上一次串連中的包迷路後重新出現,影響新串連。TCP資料包可能由於路由器異常而迷路,在迷路期間,資料包發送方可能因逾時而重發這個包,迷路的資料包在路由器恢複後也會被送到目的地,這個迷路的資料包就稱為Lost Duplicate。在關閉一個TCP串連後,如果馬上使用相同的IP地址和連接埠建立新的TCP串連,那麼有可能出現前一個串連的迷路重複資料包在前一個串連關閉後再次出現,影響建立立的串連。為了避免這一情況,TCP協議不允許使用處於TIME_WAIT狀態的串連的IP和連接埠啟動一個新串連,只有經過2MSL的時間,確保上一次串連中所有的迷路重複資料包都已消失在網路中,才能安全地建立新串連。

  對於Client而言,每個串連都需要佔用一個連接埠,而系統允許的可用連接埠數不足65000個(這也是在TCP參數最佳化後才能達到)。因此,如果Client發起過多的串連並主動關閉(假設沒有重用連接埠或者串連多個Server),就會有大量的串連在關閉後處於TIME_WAIT狀態,等待2MSL的時間後才能釋放網路資源(包括連接埠),於是Client會由於缺少可用連接埠而無法建立串連。

  對Server而言(特別是處理高並發短串連的Server),Server端與Client建立的串連是使用同一個連接埠的,即監聽的連接埠,每個串連通過一個五元組區分,包括源IP地址、源連接埠、傳輸層協議號(協議類型)、目的IP地址、目的連接埠,因而在理論上,Server不受系統連接埠數的限制。但是,Server對每個連接埠上的串連數是有限制的,它要使用雜湊表記錄連接埠上的每個串連,並受到檔案描述符的最大開啟數的限制。所以,如果Server主動關閉串連,同樣會有大量的串連在關閉後處於TIME_WAIT狀態,等待2MSL的時間後才能釋放網路資源(包括雜湊表上的串連記錄和檔案描述符),於是Server會由於達到雜湊表和檔案描述符的限制而無法接受新串連,造成效能的急劇下滑,效能曲線會持續產生嚴重的波動。對於這種情況,有三種應對方式:

  1. 試圖讓Client主動關閉串連,由於每個Client的並發量都比較低,因而不會產生效能瓶頸。
  2. 最佳化Server的系統TCP參數,使其網路資源的最大值、消耗速度和恢複速度達到平衡。
  3. 改寫TCP協議,重新實現底層代碼,不過該方式難度很大,而且系統的穩定性和安全性可能受到影響。

 下文:Windows系統下的TCP參數最佳化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.