TCP連接管理
TCP狀態轉換圖中,共有11種狀態:
- CLOSED:關閉狀態,沒有連接活動或正在進行
- LISTEN:監聽狀態,服務器正在等待連接進入
- SYN_RCVD:收到一個連接請求,尚未確認
- SYN_SENT:已經發出連接請求,等待確認
- ESTABLISHED:連接建立,正常數據傳輸狀態
- FIN_WAIT 1:(主動關閉)已經發送關閉請求,等待確認
- FIN_WAIT 2:(主動關閉)收到對方關閉確認,等待對方關閉請求
- TIME_WAIT:完成雙向關閉,等待所有分組死掉
- CLOSING:雙方同時嘗試關閉,等待對方確認
- CLOSE_WAIT:(被動關閉)收到對方關閉請求,已經確認
- LAST_ACK:(被動關閉)等待最後一個關閉確認,並等待所有分組死掉
TCP建立連接過程中需要解決的問題:
- 要使每一方能夠確知對方的存在
- 要允許雙方協商一些參數(如最大窗口值、是否使用窗口擴大選項等)
- 能夠對運輸實體資源(如緩存大小、連接表中的項目等)進行分配
TCP連接的建立採用客戶服務器方式。主動發起連接建立的應用進程叫做客戶,而被動等待建立連接的應用進程叫做服務器
TCP連接的建立:
主機A爲TCP客戶程序,主機B爲TCP服務器程序
- 首先,B的TCP服務器進程創建傳輸控制塊TCB。準備接受客戶進程的連接請求。然後服務器進程就處於LISTEN(收聽)狀態,等待客戶連接請求。如果有,即做出響應。
- A的TCP客戶進程創建傳輸控制模塊TCB。然後,在打算建立TCP連接時,向B發出連接請求報文段,這時首部中的同步位SYN被置爲1,同時選擇一個初始序號client_isn。這個報文段不攜帶數據,但要消耗一個序號。這時,TCP客戶進程進入SYN-SENT(同步已發送)狀態。(第一次握手)
- B收到連接請求報文段後,如果同意建立連接,則向A發送確認。在報文段中把SYN和ACK爲都置爲1,確認號爲client_isn+1,同時也爲自己選擇一個初始序號server_isn。這個報文段也不能攜帶數據,但同樣要消耗一個序號。這時TCP服務器進程進入SYN-RCVD(同步收到)狀態。(第二次握手)
- TCP客戶收到B的確認後,還要向B給出確認。確認報文段ACK置1,確認號爲server_isn+1,序號爲client_isn+1.這時,TCP連接已經建立,A進入ESTABLISHED(已建立連接)狀態。(第三次握手)
爲什麼需要進行第三次握手?
這主要時爲了防止已經失效的連接請求報文段傳送到B而產生錯誤。加入A發送了一條連接請求,這條請求在網絡層滯留了很久纔到達B,這本來是一條早已失效的請求報文,但是B收到後,仍向A發送一個確認報文,同意建立連接。如果沒有第三次握手的過程,就建立了一條冗餘的連接。但是由於存在第三次握手,A告訴B這說一條失效的請求報文,因此這條冗餘的連接就不會建立。
TCP連接的釋放:
數據傳輸結束後,通信的雙方都可以釋放連接。此時A和B都處於ESTABLISHED狀態。
- A把數據釋放報文段首部的終止控制符FIN置1.其序號爲seq,它等於前面已傳送過的數據的最後一個字節的序號加1.這時A進入FIN-WAIT-1(終止等待1)狀態,等待B的確認。注意,TCP規定,FIN報文段即使不攜帶數據,它也消耗一個序號。
(第一次握手) - B收到連接釋放報文段後發送確認,確認號是seq+1,序號爲B前面已經傳送過的數據的最後一個字節的序號加1。然後B進入CLOSE-WAIT(關閉等待)狀態。TCP服務器進程這時通知高層進程,因而A到B這個方向的連接就釋放了,這時TCP連接處於半關閉狀態,即A已經沒有數據要發送了,但B發送數據,A仍要接收,也就是說,從B到A這個方向的連接並未關閉,這個狀態可能會持續一段時間。A收到來自B的確認後,就進入FIN-WAIT-2(終止等待2)狀態,等待B發出的連接釋放報文段(第二次握手)
- 若B已經沒有要向A發送的數據,其應用進程就通知TCP釋放連接。這時B發出的連接釋放報文將FIN位置爲1.現假定B的需要爲w。B還必須重複上述已經發送過的確認號seq+1.這是B就進入LAST-ACK(最後確認)狀態,等待A的確認。(第三次握手)
- A在收到B的連接釋放報文段後,必須對此發出確認。在確認報文段中把ACK置1,確認號w+1,而自己的序號是seq+1.然後進入到TIME-WAIT(時間等待)狀態。經過時間等待計時器設置的時間2MSL後,A才進入到CLOSED狀態。時間MSL叫做最長報文段壽命。等待一段時間後,A進入CLOSED狀態。當A撤銷響應的傳輸控制塊TCB後,就結束了這次TCP連接。B只要收到了A發出的確認,就進入CLOSED狀態。同樣,B在撤銷相應的控制傳輸快TCB後,就結束了這次TCP握手,這意味着B結束TCP連接的時間要比A更早一些。(第四次握手)
爲什麼A在TIME-WAIT狀態必須等待2MSL的時間?
- 爲了保證A發送的最後一個ACK報文段能夠到達B。這個ACK報文段可能丟失,因而使處在LAST-ACK狀態的B收不到對已發送的FIN+ACK報文段的確認。
- 防止已失效的連接請求報文段出現在本連接中。A在發送完最後一個ACK報文段後,再經過時間2MSL,就可以使本連接的時間內所產生的所有報文段都從網絡中消失,這樣就可以使下一個新的連接中不會出現這種舊的連接請求報文段。