在以前對TCP協議的介紹中,說到了其中它的一個特色是面向鏈接。今天就來介紹一下它的鏈接和斷開過程。安全
面向鏈接指的是採用TCP協議通信,在數據傳輸以前必須先創建鏈接,通信完成以後,必須關閉鏈接。服務器
創建鏈接的過程爲三次握手過程,其做用是:網絡
一、使得通信雙發都作好通信的準備spa
二、告訴對端本端通信所選用的報文標識號計算機網絡
三、防止已失效的鏈接請求報文段又忽然傳遞到了服務端,從而產生錯誤server
關閉鏈接的過程爲四次揮手,因爲TCP的全雙工的通信。因此每一個方向都必須單獨進行關閉。當一方完成它的數據發送任務後就能發送一個FIN來終止這個方向的鏈接。收到一個FIN只意味着這一方向上沒有數據流動,一個TCP鏈接在收到一個FIN後仍能繼續發送數據。首先進行關閉的一方將執行主動關閉,而另外一方執行被動關閉。blog
TCP三次握手和四次揮手過程:資源
當客戶鏈接收到服務器發送的結束報文段(報文段6)以後,並無直接進入CLOSED狀態,而是轉移到TIME_WAIT狀態。在這個狀態,客戶端鏈接要等待一段長爲2MSL(MSL:報文段最大生存時間)的時間,才能徹底關閉。路由
TIME_WAIT狀態存在的緣由:cli
一、可靠的終止鏈接。 假設圖中用於確認服務器報文段6的TCP報文段7丟失,那麼服務器將重發結束報文段。所以客戶端須要停留在某個狀態處理重複收到的結束報文段(即向服務器發送確認報文段)。不然,客戶端將以復位報文段來回應服務器,服務器則認爲只是一個錯誤,由於它指望收到的是一個像報文段7那樣的確認報文段。
二、保證讓遲來的TCP報文段有足夠的時間識別並丟棄。 在Linux系統上,一個TCP端口不能被同時打開兩次及以上。當一個TCP鏈接處於TIME_WAIT狀態時,咱們沒法當即使用該鏈接佔用的端口號來創建一個新鏈接。所以,若是沒有TIME_WAIT狀態,則應用程序可以當即創建一個和剛關閉的鏈接類似的鏈接(類似是指它們具備相同的IP地址和端口號)。這個新的和原來類似的鏈接被稱爲原來的鏈接的化身。新的化身可能接收到屬於原來的鏈接的、攜帶應用程序的TCP報文段(即遲到的報文段),這顯然是不該該發生的,這是存在的第二個緣由。
另外,由於TCP報文段的最大生存時間是MSL,因此堅持2MSL時間的TIME_WAIT狀態可以確保網絡上兩個傳輸方向上還沒有被接受到的、遲到的報文段都已經消失(被中轉路由器丟棄)。所以,一個鏈接的新的化身能夠再2MSL時間以後安全的創建,而絕對不會接收到屬於原來鏈接的應用程序數據,這就是TIME_WAIT要持續2MSL時間的緣由。
那麼TCP爲何要進行三次握手和四次揮手呢?
「三次握手」的目的是「爲了防止已失效的鏈接請求報文段忽然又傳送到了服務端,於是產生錯誤」。
謝希仁版《計算機網絡》中的例子是這樣的,「已失效的鏈接請求報文段」的產生在這樣一種狀況下:client發出的第一個鏈接請求報文段並無丟失,而是在某個網絡結點長時間的滯留了,以至延誤到鏈接釋放之後的某個時間纔到達server「。
原本這是一個早已失效的報文段。但server收到此失效的鏈接請求報文段後,就誤認爲是client再次發出的一個新的鏈接請求。因而就向client發出確認報文段,贊成創建鏈接。假設不採用「三次握手」,那麼只要server發出確認,新的鏈接就創建了。因爲如今client並無發出創建鏈接的請求,所以不會理睬server的確認,也不會向server發送數據。但server卻覺得新的運輸鏈接已經創建,並一直等待client發來數據。這樣,server的不少資源就白白浪費掉了。採用「三次握手」的辦法能夠防止上述現象發生。例如剛纔那種狀況,client不會向server的確認發出確認。server因爲收不到確認,就知道client並無要求創建鏈接。」。主要目的防止server端一直等待,浪費資源。
四次揮手的緣由:在四次揮手過程當中,報文段6中也包含了確認信息,爲何還用報文段5單獨先發一遍,那麼這個報文段5能夠背省略麼?
實際上,僅用於確認目的的確認報文段5是能夠省略的,由於報文段6中也攜帶了該確認信息。確認報文段5是否出如今鏈接斷開的過程當中,取決於TCP的延遲確認特性。
TCP鏈接是全雙工的,因此它容許兩個方向的數據傳輸被獨立關閉。即,通訊的一方能夠髮結束報文段給對方,告訴它本端已經完成了數據的發送,但容許繼續接收來自對方的數據,直到對方也發送報文段結束。因此當客戶端發送結束報文段後,服務器那裏可能還有數據要發送,就先發送一個確認報文段表示已經接收到客戶端發送過來的結束報文段,直到將數據發送完畢後再結束鏈接。
延遲確認:即服務器不立刻確認上次收到的數據,而是在一段延遲時間後查看本端是否有數據須要發送,若是有,則和確認信息一塊兒發出。由於服務器對客戶的請求處理很快,因此他發送確認報文段的時候老是有數據一塊兒發送。延遲確承認以減小發送TCP報文段的數量。而因爲用戶的輸入速度明顯慢於客戶端程序的處理速度,因此客戶端的確認報文段老是不攜帶任何應用程序。