TCP/IP狀態圖

這是網絡編程的基礎,tcp的狀態轉移圖說到底就是一個狀態機的不同狀態之間的轉換關係以及觸發這些狀態需要的條件,一共存在11個狀態,我們來逐一分析:

090310142823

1.CLOSED:起始點,在超時或者連接關閉時候進入此狀態。

2.LISTEN:svr端在等待連接過來時候的狀態,svr端爲此要調用socket, bind,listen函數,就能進入此狀態。此稱爲應用程序被動打開(等待客戶端來連接)。

3.SYN_SENT:客戶端發起連接,發送SYN給服務器端。如果服務器端不能連接,則直接進入CLOSED狀態。

4.SYN_RCVD:跟3對應,服務器端接受客戶端的SYN請求,服務器端由LISTEN狀態進入SYN_RCVD狀態。同時服務器端要回應一個ACK,同時發送一個SYN給客戶端;另外一種情況,客戶端在發起SYN的同時接收到服務器端得SYN請求,客戶端就會由SYN_SENT到SYN_RCVD狀態。

5.ESTABLISHED:服務器端和客戶端在完成3次握手進入狀態,說明已經可以開始傳輸數據了。

以上是建立連接時服務器端和客戶端產生的狀態轉移說明。相對來說比較簡單明瞭,如果你對三次握手比較熟悉,建立連接時的狀態轉移還是很容易理解。

接下來服務器端和客戶端就進行數據傳輸。。。。,當然,裏面也大有學問,就此打住,稍後再表。

下面,我們來看看連接關閉時候的狀態轉移說明,關閉需要進行4次雙方的交互,還包括要處理一些善後工作(TIME_WAIT狀態),注意,這裏主動關閉的一方或被動關閉的一方不是指特指服務器端或者客戶端,是相對於誰先發起關閉請求來說的:

6.FIN_WAIT_1:主動關閉的一方,由狀態5進入此狀態。具體的動作時發送FIN給對方。

7.FIN_WAIT_2:主動關閉的一方,接收到對方的FIN ACK,進入此狀態。由此不能再接收對方的數據。但是能夠向對方發送數據。

8.CLOSE_WAIT:接收到FIN以後,被動關閉的一方進入此狀態。具體動作時接收到FIN,同時發送ACK。

9.LAST_ACK:被動關閉的一方,發起關閉請求,由狀態8進入此狀態。具體動作時發送FIN給對方,同時在接收到ACK時進入CLOSED狀態。

10.CLOSING:兩邊同時發起關閉請求時,會由FIN_WAIT_1進入此狀態。具體動作是,接收到FIN請求,同時響應一個ACK。

11.TIME_WAIT:最糾結的狀態來了。從狀態圖上可以看出,有3個狀態可以轉化成它,我們一一來分析:

a.由FIN_WAIT_2進入此狀態:在雙方不同時發起FIN的情況下,主動關閉的一方在完成自身發起的關閉請求後,接收到被動關閉一方的FIN後進入的狀態。

b.由CLOSING狀態進入:雙方同時發起關閉,都做了發起FIN的請求,同時接收到了FIN並做了ACK的情況下,由CLOSING狀態進入。

c.由FIN_WAIT_1狀態進入:同時接受到FIN(對方發起),ACK(本身發起的FIN迴應),與b的區別在於本身發起的FIN迴應的ACK先於對方的FIN請求到達,而b是FIN先到達。這種情況概率最小。

關閉的4次連接最難理解的狀態是TIME_WAIT,存在TIME_WAIT的2個理由:

1.可靠地實現TCP全雙工連接的終止。

2.允許老的重複分節在網絡中消逝。




------------------------------

同時打開

兩個應用程序同時執行主動打開的情況是可能的,雖然發生的可能性較低。每一端都發送一個SYN,並傳遞給對方,且每一端都使用對端所知的端口作爲本地端口。例如:

主機a中一應用程序使用7777作爲本地端口,並連接到主機b 8888端口做主動打開。

主機b中一應用程序使用8888作爲本地端口,並連接到主機a 7777端口做主動打開。

tcp協議在遇到這種情況時,只會打開一條連接。

這個連接的建立過程需要4次數據交換,而一個典型的連接建立只需要3次交換(即3次握手)

但多數伯克利版的tcp/ip實現並不支持同時打開。

SYN_RCVD與SYN_SEND都是轉換爲ESTABLISHED的中間狀態,目標是兩端均轉換到ESTABLISHED狀態。

同時關閉

如果應用程序同時發送FIN,則在發送後會首先進入FIN_WAIT_1狀態。在收到對端的FIN後,回覆一個ACK,會進入CLOSING狀態。在收到對端的ACK後,進入TIME_WAIT狀態。這種情況稱爲同時關閉。

同時關閉也需要有4次報文交換,與典型的關閉相同。


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