TCP三次握手/四次揮手及其狀態分析

前面CLOSE_WAIT狀態分析與TIME_WAIT狀態分析其實都是TCP斷開連接過程中的兩個狀態.本文繼續介紹下TCP連接三次握手,四次揮手的過程及其中間的狀態

三次握手原理:

第一次握手:客戶端發送syn包(syn=j)到服務器,等待服務器確認.

第二次握手:服務器收到syn包,必須確認(ack=j+1),同時自己發送一個syn包(syn=k),即SYN+ACK包.

第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包(ack=k+1).

圖示:

CLINET -----          SYN(j)         ----- SERVER  

SERVER -----  ACK(j+1) SYN(k) ----- CLINET

CLINET -----         ACK(k+1)     ----- SERVER

客戶端發送syn包,進入SYN_SEND狀態,服務器收到sync包,進入SYN_RECV狀態.

客戶端收到服務器端的SYN+ACK包進入ESTABLISHED狀態.

服務器端收到客戶機端的ack包,進入ESTABLISHED狀態.

簡單的說:

客戶端問服務器:你允許我和你建立連接麼?

服務器端說:可以,那你也允許我和你建立連接麼?

客戶端說:可以.

於是,他們之間就建立起連接了.

四次分手原理:

由於TCP連接是全雙工的,因此每個方向都必須單獨進行關閉.這個原則是當一方完成它的數據發送任務後就能發送一個FIN來終止這個方向的連接.收到一個 FIN只意味着這一方向上沒有數據流動,一個TCP連接在收到一個FIN後仍能發送數據.首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉.

(1)客戶端A發送一個FIN,用來關閉客戶A到服務器B的數據傳送.

(2)服務器B收到這個FIN,它發回一個ACK,確認序號爲收到的序號加1.

(3)服務器B關閉與客戶端A的連接,發送一個FIN給客戶端A.

(4)客戶端A發回ACK報文確認,並將確認序號設置爲收到序號加1.

圖示:

CLINET  ---   FIN  --- SERVER

SERVER ---   ACK  --- CLINET 

SERVER ---   FIN  --- CLINET 

CLINET  ---   ACK --- SERVER

客戶端主動關閉連接,發送FIN包,進入FIN_WAIT_1狀態.接收端收到FIN包,進入CLOSE_WAIT狀態.

客戶端收到服務器的ACK包,進入FIN_WAIT_2狀態.

服務器發送FIN包,進入LAST_ACK狀態.客戶端接收到FIN包,進入TIME_WAIT狀態

服務器收到ACK包,進入CLOSED狀態.

簡單的說:

客戶端問服務器:我們斷開連接吧?

服務器端說:可以,我將不再接收你的數據.

服務器端問服務器:我將要跟你斷開連接了,可以吧?

客戶端說:可以.

客戶端說:可以.

於是,他們之間的連接就斷開了.

TCP連接正常建立和終止過程及對應狀態如圖:


 http://hi.csdn.net/space-4175647-do-album-picid-512430.html

這裏有個連接同時打開的問題,跟前面文章中說的五元組問題一樣,很難出現,但如果指定本地和對方兩端的端口號還是能製造出這樣的情況.

兩端都是在SYN_SENT狀態下收到對方的SYN包而進入SYN_RCVD狀態,然後都會發送SYN+ACK包,當兩端都會收到該包時,狀態會變成ESTABLISHED.

圖示:

CLINET  ---        SYN     --- SERVER       SERVER  ---      SYN       --- CLINET 

SERVER ---   SYN+ACK  --- CLINET       CLINET   ---   SYN+ACK  --- SERVER  

TCP連接同時建立過程及對應狀態如圖:

 http://hi.csdn.net/space-4175647-do-album-picid-512432.html

繼續說下CLOSING狀態,當兩端幾乎同時關閉連接時,兩端都是在FIN_WAIT_1狀態下收到對方的FIN包,會進入CLOSING狀態.然後都會發送最後的ACK包.當兩端都會收到該包時,狀態會變成TIME_WAIT.

圖示:

CLINET  ---   FIN  --- SERVER       SERVER   ---   FIN  --- CLINET 

SERVER ---   ACK  --- CLINET       CLINET   ---   ACK  --- SERVER  

TCP連接同時關閉過程及對應狀態如圖:

 http://hi.csdn.net/space-4175647-do-album-picid-512433.html

還有個問題:爲什麼建立連接協議是三次握手,而關閉連接卻是四次握手呢?

這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送.但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了.但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的.

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/ustcgy/archive/2010/03/08/5356911.aspx

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