TCP連接的建立與終止過程

來源:文萃谷 7.35K

引導語:tcp協議在進行工作時需要進過三次握手四次揮手的過程,以下是小編整理的TCP連接的建立與終止過程,歡迎參考閲讀!

TCP連接的建立與終止過程

  1.三次握手

TCP是面向連接的,無論哪一方向另一方發送數據之前,都必須先在雙方之間建立一條連接。在TCP/IP協議中,TCP協議提供可靠的連接服務,連接是通過三次握手進行初始化的。三次握手的目的是同步連接雙方的序列號和確認號並交換 TCP窗口大小信息。

第一次握手:建立連接。客户端發送連接請求報文段,將SYN位置為1,Sequence Number為x;然後,客户端進入SYN_SEND狀態,等待服務器的確認;

第二次握手:服務器收到SYN報文段。服務器收到客户端的SYN報文段,需要對這個SYN報文段進行確認,設置Acknowledgment Number為x+1(Sequence Number+1);同時,自己自己還要發送SYN請求信息,將SYN位置為1,Sequence Number為y;服務器端將上述所有信息放到一個報文段(即SYN+ACK報文段)中,一併發送給客户端,此時服務器進入SYN_RECV狀態;

第三次握手:客户端收到服務器的SYN+ACK報文段。然後將Acknowledgment Number設置為y+1,向服務器發送ACK報文段,這個報文段發送完畢以後,客户端和服務器端都進入ESTABLISHED狀態,完成TCP三次握手。

為什麼要三次握手?

為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。

具體例子:“已失效的連接請求報文段”的產生在這樣一種情況下:client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段後,就誤認為是client再次發出的`一個新的連接請求。於是就向client發出確認報文段,同意建立連接。假設不採用“三次握手”,那麼只要server發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以為新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。採用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。”

  2.四次揮手

當客户端和服務器通過三次握手建立了TCP連接以後,當數據傳送完畢,肯定是要斷開TCP連接的啊。那對於TCP的斷開連接,這裏就有了神祕的“四次分手”。

第一次分手:主機1(可以使客户端,也可以是服務器端),設置Sequence Number,向主機2發送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態;這表示主機1沒有數據要發送給主機2了;

第二次分手:主機2收到了主機1發送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number為Sequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我“同意”你的關閉請求;

第三次分手:主機2向主機1發送FIN報文段,請求關閉連接,同時主機2進入LAST_ACK狀態;

第四次分手:主機1收到主機2發送的FIN報文段,向主機2發送ACK報文段,然後主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段以後,就關閉連接;此時,主機1等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,主機1也可以關閉連接了。

  為什麼要四次分手?

TCP協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議。TCP是全雙工模式,這就意味着,當主機1發出FIN報文段時,只是表示主機1已經沒有數據要發送了,主機1告訴主機2,它的數據已經全部發送完畢了;但是,這個時候主機1還是可以接受來自主機2的數據;當主機2返回ACK報文段時,表示它已經知道主機1沒有數據發送了,但是主機2還是可以發送數據到主機1的;當主機2也發送了FIN報文段時,這個時候就表示主機2也沒有數據要發送了,就會告訴主機1,我也沒有數據要發送了,之後彼此就會愉快的中斷這次TCP連接。

  為什麼要等待2MSL?

MSL:報文段最大生存時間,它是任何報文段被丟棄前在網絡內的最長時間。

原因有二:

保證TCP協議的全雙工連接能夠可靠關閉

保證這次連接的重複數據段從網絡中消失

第一點:如果主機1直接CLOSED了,那麼由於IP協議的不可靠性或者是其它網絡原因,導致主機2沒有收到主機1最後回覆的ACK。那麼主機2就會在超時之後繼續發送FIN,此時由於主機1已經CLOSED了,就找不到與重發的FIN對應的連接。所以,主機1不是直接進入CLOSED,而是要保持TIME_WAIT,當再次收到FIN的時候,能夠保證對方收到ACK,最後正確的關閉連接。

第二點:如果主機1直接CLOSED,然後又再向主機2發起一個新連接,我們不能保證這個新連接與剛關閉的連接的端口號是不同的。也就是説有可能新連接和老連接的端口號是相同的。一般來説不會發生什麼問題,但是還是有特殊情況出現:假設新連接和已經關閉的老連接端口號是一樣的,如果前一次連接的某些數據仍然滯留在網絡中,這些延遲數據在建立新連接之後才到達主機2,由於新連接和老連接的端口號是一樣的,TCP協議就認為那個延遲的數據是屬於新連接的,這樣就和真正的新連接的數據包發生混淆了。所以TCP連接還要在TIME_WAIT狀態等待2倍MSL,這樣可以保證本次連接的所有數據都從網絡中消失。

熱門標籤