客戶端狀態的變化:
客戶端建立套接字之後會connect伺服器,這時客戶端會傳送乙個syn到伺服器,狀態轉換到syn_sent並等待伺服器的回覆,收到服務端的回覆syn+ack(同乙個報文)之後客戶端會回覆ack此時狀態轉換到established,正常資料互動完成之後客戶端會close套接字此時傳送乙個fin報文,狀態轉換到fin_wait_1,同時等待服務端的回覆,此時有三種情況:
(1)收到服務端的ack但此時服務端沒有關閉套接字。狀態轉換到了fin_wait_2,然後再等待服務端關閉套接字發出的fin,如果收到則回覆ack,狀態轉換到time_wait狀態,等待2msl超時之後自動轉換為closed狀態。
(2)服務端同時也在關閉套接字,此時客戶端會收到syn並發出ack,狀態轉換到closing,之後等待服務端回覆ack,若收到ack則轉到time_wait狀態。
(3)伺服器在收到客戶端fin之後立馬關閉套接字,此時客戶端會收到乙個ack和fin並發出ack,狀態轉換到time_wait狀態。
伺服器狀態的變化:
服務端建立套接字之後呼叫listen函式將套接字有乙個未連線的主動套接字轉換為被動套接字,指示核心應接受指向該套接字的連線請求,套接字狀態由close轉換為listen,等待客戶端連線。所以服務端是被動接收連線的,服務端會先收到syn,收到之後會立馬傳送乙個syn+ack(同乙個報文),此時狀態轉換到syn_rcvd並等待客戶端回覆ack,此時套接字處於未完成連線佇列中,如果收到ack狀態會轉換到established,套接字處於已完成連線佇列中,注意的是未完成連線佇列和已完成連線佇列之和不能超過listen設定的最大連線個數。這時服務端和客戶端可以進行資料互動,客戶端接收完資料之後主動close套接字,此時服務端會收到fin並回覆ack,狀態轉換到lose_wait,當服務端的應用層也close套接字時服務端會發生乙個fin狀態轉換到last_ack然後會收到客戶端回覆的ack,狀態轉換到closed。
為什麼釋放連線需要time_wait?
回憶一下我們最終的那個fin與ack,被動關閉方傳送fin,並等待主動關閉方返回的ack。我們假設最終的ack丟失,被動關閉方將需要重新傳送它的最終那個fin,主動關閉方必須維護狀態資訊(time_wait),以允許它重發最終的那個ack。如果沒有了這個狀態,當他第二次收到fin時,會響應乙個rst(也是一種型別的tcp分節),會被伺服器解釋成乙個錯誤。
目的:為了tcp打算執行必要的工作以徹底終止某個連線兩個方向上的資料流(即全雙工關閉),那麼他必須要正確處理連線終止四個分節中任何乙個分節丟失的情況
處於time_wait這個狀態時,此套接字上的繫結了資源,將在2msl(最大報文生存時間)內不可再使用。選擇2msl這個時間是為了避免出現上一次連線中被動關閉端重**送的資料報。
我們假設ip1:port1和ip2:port2 之間有乙個tcp連線。我們關閉了這個鏈結,過一段時間後在相同ip和埠之間建立了另乙個連線。tcp必須防止來自之前那個連線的老的重複分組在新連線上出現。為了做到這一點,tcp將不復用處於time_wait狀態的連線。2msl的時間足以讓某個方向上的分組存活msl秒後被丟棄,另乙個方向上的應答也最多存活msl秒後被丟棄。
狀態轉換圖:
關閉tcp連線
luolei localhost sudo netstat a grep ssh tcp 0 0 192.168.1.10 40278 com ssh established unix 2 acc stream listening 7565 tmp ssh uyvolk4882 agent.4882...
TCP長短連線
tcp 長短連線 1 什麼是 tcp長連線 從應用層來看,就是 client 到server 建立一次連線,傳送多個資料報,直到不再與 server 通訊時關閉連線。connect send recv send recv close。從傳輸層來看,使用的是 keep alive timer 實現 t...
Tcp 斷開連線
tcp協議規定,對於已經建立的連線,網路雙方要進行四次握手才能成功斷開連線,如果缺少了其中某個步驟,將會使連線處於假死狀態,連線本身占用的資源不會被釋放。網路伺服器程式要同時管理大量連線,所以很有必要保證無用連線完全斷開,否則大量僵死的連線會浪費許多伺服器資源。在眾多tcp狀態中,最值得注意的狀態有...