網絡編程基礎(3)-協議概要-TCP的連接管理

連接的建立與斷開

TCP是一個面向連接的協議。無論哪一方發送數據之前,都必須先在雙方之間建立一條連接。

三次握手建立連接

這裏寫圖片描述
第一次握手:客戶端向服務端發起連接請求包(稱爲SYN包),設置SYN標誌位爲1,設置序列號seq爲X。

第二次握手:服務端收到客戶端發來的SYN包後,向客戶端發送設置了SYN標誌和ACK標誌都爲1,序列號seq爲Y,確認應答號ack爲客戶序列號+1(ack=X+1)的包(稱爲SYN+ACK包)。

第三次握手:客戶端收到服務端發送來的SYN+ACK包後,向服務端發送一個設置了ACK標誌爲1,序列號seq爲服務端確認應答號,確認應答號ack爲服務端序列號+1(ack=Y+1)的包(稱爲ACK包)。
通過三次握手後,就可以相互發送數據了。

當一個連接建立時,雙方會通過在TCP首部中寫入MSS選項(MSS選項只能出現在SYN包中)通告各自的MSS(最大報文段長度),然後在兩者之間選擇一個較小的MSS值使用。如果某一方的MSS值被省略,則MSS設定爲默認值536字節(IP包的長度不超過576字節,包括IP首部20字節、TCP首部20字節、MSS536字節)。一般來說,如果沒有分段發生,MSS值還是越大越好。這個值TCP協議在實現的時候往往用MTU值代替(需要減去IP首部20字節和TCP首部20字節),所以一般MSS值1460。

連接的建立可能超時。很多情況下可能導致連接超時。如服務端主機不在正常狀態,這時候,客戶端會隔一段時間重複發送SYN包,試圖建立連接,當多次重複依然沒能建立連接之後,客戶端放棄連接。

四次揮手斷開連接

斷開一個TCP連接需要四次揮手,TCP連接是全雙工的(數據在兩個方向上能同時傳遞),每個方向必須單獨地進行關閉。

這裏寫圖片描述

第一次揮手:客戶端給服務端發送TCP包,用來關閉客戶端到服務端的數據傳送。將標誌位FIN和ACK置爲1,序列號seq爲X,確認應答號ack爲Z。

第二次揮手:服務端收到FIN包後,發回一個設置了ACK標誌爲1,序列號seq爲收到的客戶確認應答號Z,確認應答ack爲收到的客戶序列號+1(ack=X+1)包。

第三次揮手:服務端向客戶端發送TCP包,用來關閉服務端到客戶端的數據傳送。將FIN和ACK標誌置爲1,序列號seq爲Y,確認應答號ack爲收到的客戶序列號+1(ack = X+1)的包。

第四次揮手:客戶端收到服務端發來的FIN包後,發回一個設置了ACK標誌爲1,序列號seq爲收到的服務端的確認應答號(seq=X+1),確認應答號ack爲收到的服務端的序列號+1(ack=Y+1)包。
經過四次揮手,連接徹底斷開。

這裏注意下,TCP有半關閉的特性,TCP提供了連接的一端在結束它的發送後還能繼續接收來自另一端數據的能力。如在上面的四次揮手圖中,在第二次揮手後,服務端可以繼續向客戶端發送數據,客戶端可以接收數據並回復確認應答。

TCP狀態機

經典的TCP狀態變遷圖:

這裏寫圖片描述

各種狀態的解釋:

CLOSED:初始狀態或關閉狀態。對服務端和客戶端雙方都一樣。

LISTEN:監聽狀態。服務端等待連接進入。

SYN_SENT:客戶端已經發送了連接請求,等待服務端確認。

SYN_RCVD:服務端收到客戶端的連接請求即進入該狀態,但尚未確認,隨後發送ACK+SYN給客戶端。

ESTABLISHED:連接已經建立成功,進入正常數據傳輸狀態。

FIN_WAIT_1:(主動關閉方)發送關閉請求,等待確認。

CLOSE_WAIT:(被動關閉方)收到對方的關閉請求,回覆確認應答,進入該狀態。

FIN_WAIT_2:(主動關閉方)收到對方的關閉確認應答,等待對方關閉請求。

LAST_ACK:(被動關閉方)發送關閉請求,等待確認。當收到確認應答後就進入CLOSED狀態。

TIME_WAIT:(主動關閉方)收到對方關閉請求,進入該狀態,隨即發送最後一個確認應答。等待2MSL後回到CLOSED狀態。如果在FIN_WAIT_1狀態下,收到對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。

CLOSING:雙方同時關閉連接,就會出現該狀態。

由下面的狀態變化過程,對照上面的狀態變遷圖,以便明白每個狀態的變化。
這裏寫圖片描述

TIME_WAIT狀態

time_wait狀態又稱2MSL(報文段最大生存時間)等待狀態,主動關閉方收到對方的FIN包後就進入TIME_WAIT狀態,隨即發回最後一個ACK,該連接必須在此狀態停留2倍MSL的時間。
目的:
1,實現可靠的連接斷開。如果主動關閉方發送的最後一個ACK丟失了,被動關閉方會重發FIN包,因此主動關閉端需要維持狀態信息,以允許它重新發送最終的ACK。
2,防止這些迷路遲到的報文影響新連接,你要知道,有些自做主張的路由器會緩存IP數據包,如果連接被重用了,那麼這些延遲收到的包就有可能會跟新連接混在一起。此狀態期間,該連接不能再被使用,任何遲到的報文都會丟棄。

復位報文段

無論何時在一個TCP連接中出現差錯,TCP都會發送一個復位報文段(TCP首部中RST位置爲1)。

目的端口未打開:連接請求到達時,目的端口沒有進程監聽。對於UDP,當一個數據報到達目的端口時,如果該端口沒有在使用,那麼將會產生一個ICMP端口不可達的消息。對於TCP則產生一個復位報文段。

異常終止連接:通過發送FIN的方式正常終止連接,稱爲有序釋放。因爲在所有排隊數據都發送完後才發送FIN,一般情況下沒有數據丟失。而通過發送一個RST報文段報文段的方式中途終止連接,稱爲異常釋放。這是因爲發送RST報文段關閉連接時,不必等緩衝區的包都發出去,直接就丟棄緩衝區的包。而接收端收到RST報文段後,也根本不發送ACK包來確認,而是直接終止連接,並通知應用層連接復位。

檢測半打開連接:如果一方已經關閉或異常終止連接而另一方卻還不知道,我們將這樣的TCP連接稱爲半打開(Half-Open)的。任何一端的主機異常都可能導致發生這種情況。只要不打算在半打開連接上傳輸數據,仍處於連接狀態的一方就不會檢測另一方已經出現異常。半打開連接的另一個常見原因是當服務器主機突然掉電而不是正常的結束服務應用程序後再關機,服務器主機重啓後,從客戶向服務器發送另一行字符。由於服務器的TCP已經重新啓動,它將丟失復位前連接的所有信息,因此它不知道數據報文段中提到的連接。TCP的處理原則是接收方以復位作爲應答。

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