TCP/IP狀態詳解

      今天犯懶了,本來自己也做了一些相應的筆記,但是發現這篇寫的更好一些,簡單易懂,而且有圖有真相,爲了方便以後查看,在此轉載了,在此基礎上加了自己的筆記

     
          TCP正常建立和關閉的狀態變化
        
                         
 
TCP連接的建立可以簡單的稱爲“三次握手”,而連接的中止則可以叫做“四次握手”。
 
    建立連接
 
    在TCP/IP協議中,TCP協議提供可靠的連接服務,採用三次握手建立一個連接。
第一次握手:建立連接時,客戶端發送syn包到服務器,同時,當S標誌位置1時,報文攜帶開始序號 j,並進入SYN_SEND狀態,等待服務器確認;
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包,雖然是被動建立連接,但是同樣要申請一個不同的開始序號 k,送往客戶端,即SYN+ACK包,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。
完成三次握手,客戶端與服務器開始傳送數據,也就是ESTABLISHED狀態。

 
     結束連接 (連接終止協議)

      TCP有一個特別的概念叫做half-close,這個概念是說,TCP的連接是全雙工(可以同時發送和接收)連接,因此在關閉連接的時候,必須關閉傳和送兩個方向上的連接。客戶機給服務器一個FIN爲1 的TCP報文,然後服務器返回給客戶端一個確認ACK報文,並且發送一個FIN報文,當客戶機回覆ACK報文後(四次握手),連接就結束了。然而,如果服務器返回給客戶端一個確認ACK的報文之後,可以繼續往客戶端發送數據報,直到服務器應用程序發送完成之後,向客戶端發送FIN報文,客戶端嚮應用程序交付eof之後回覆服務器ACK報文,完成四次握手。也就是說,它們之間進行數據的收發並不衝突,當客戶端結束髮送後,由於TCP連接沒有完全斷開,仍然是可以接收數據的。

TCP的半關閉如何實現:

       如果應用程序不調用close而調用shutdown,且第2個參數值爲1,則接口的API支持半關閉,然而,大多數的應用程序是通過調用close終止兩個方向的連接。

連接建立的超時(第一次:5.5~6s  第二次:24s)

最大報文段長度(默認536字節,最終的IP數據報爲:536+20+20=576字節):MSS會以建立連接的雙方(含SYN字段)的最小MSS值傳送報文段。但如果兩端的MSS值比較大,但是中間有一段網絡的MTU值很小,爲了避免分片,只能採用路徑上的MTU發現機制

       TCP狀態變遷圖
                   

     這是一個看起來比較複雜的狀態遷移圖,因爲它包含了兩個部分---服務器的狀態遷移和客戶端的狀態遷移,如果從某一個 角度出發來看這個圖,就會清晰許多,這裏面的服務器和客戶端都不是絕對的,發送數據的就是客戶端,接受數據的就是服務器。

 

客戶端的狀態可以用如下的流程來表示:

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

以上流程是在程序正常的情況下應該有的流程,從書中的圖中可以看到,在建立連接時,當客戶端收到SYN報文的ACK以後,客戶端就打開了數據交互地 連接。而結束連接則通常是客戶端主動結束的,客戶端結束應用程序以後,需要經歷FIN_WAIT_1,FIN_WAIT_2等狀態,這些狀態的遷移就是前 面提到的結束連接的四次握手。

 

服務器的狀態可以用如下的流程來表示:

CLOSED->LISTEN->SYN收到 ->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

在建立連接的時候,服務器端是在第三次握手之後才進入數據交互狀態,而關閉連接則是在關閉連接的第二次握手以後(注意不是第四次)。而關閉以後還要 等待客戶端給出最後的ACK包才能進入初始的狀態。

 

其他狀態遷移

書中的圖還有一些其他的狀態遷移,這些狀態遷移針對服務器和客戶端兩方面的總結如下

1. LISTEN->SYN_SENT,對於這個解釋就很簡單了,服務器有時候也要打開連接的嘛。
2. SYN_SENT->SYN收到,服務器和客戶端在SYN_SENT狀態下如果收到SYN數據報,則都需要發送SYN的ACK數據報並把自己的狀態 調整到SYN收到狀態,準備進入ESTABLISHED
3. SYN_SENT->CLOSED,在發送超時的情況下,會返回到CLOSED狀態。
4. SYN_收到->LISTEN,如果受到RST包,會返回到LISTEN狀態。
5. SYN_收到->FIN_WAIT_1,這個遷移是說,可以不用到ESTABLISHED狀態,而可以直接跳轉到FIN_WAIT_1狀態並等待關 閉。

 

2MSL等待狀態

書中給的圖裏面,有一個TIME_WAIT等待狀態,這個狀態又叫做2MSL狀態,說的是在TIME_WAIT2發送了最後一個ACK數據報以後, 要進入 TIME_WAIT狀態,這個狀態是防止最後一次握手的數據報沒有傳送到對方那裏而準備的(注意這不是四次握手,這是第四次握手的保險狀態)。這個狀態在 很大程度上保證了雙方都可以正常結束,但是,問題也來了。

由於插口的2MSL狀態(插口是IP和端口對的意思,socket),使得應用程序在2MSL時間內是無法再次使用同一個插口的,對於客戶程序還好 一些,但是對於服務程序,例如httpd,它總是要使用同一個端口來進行服務,而在 2MSL時間內,啓動httpd就會出現錯誤(插口被使用)。爲了避免這個錯誤,服務器給出了一個平靜時間的概念,這是說在2MSL時間內,雖然可以重新 啓動服務器,但是這個服務器還是要平靜的等待2MSL時間的過去才能進行下一次連接。



FIN_WAIT_2狀態

這就是著名的半關閉的狀態了,這是在關閉連接時,客戶端和服務器兩次握手之後的狀態。在這個狀態下,應用程序還有接受數據的能力,但是已經無法發送 數據,但是也有一種可能是,客戶端一直處於FIN_WAIT_2狀態,而服務器則一直處於WAIT_CLOSE狀態,而直到應用層來決定關閉這個狀態。

 

RST,同時打開和同時關閉

RST是另一種關閉連接的方式,應用程序應該可以判斷RST包的真實性,即是否爲異常中止。而同時打開和同時關閉則是兩種特殊的TCP狀態,發生的 概率很小。


轉載地址:http://www.cnblogs.com/ggjucheng/p/3348492.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章