三次握手四次揮手的原理

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

1.第一次握手:創建鏈接。客戶端發送鏈接請求報文段,將SYN位置爲1,Sequence Number爲x;而後,客戶端進入SYN_SEND狀態,等待服務器的確認;網絡

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

3.第三次握手:客戶端收到服務器的SYN+ACK報文段。而後將Acknowledgment Number設置爲y+1,向服務器發送ACK報文段,這個報文段發送完畢之後,客戶端和服務器端都進入ESTABLISHED狀態,完成TCP三次握手。計算機網絡

完成了三次握手,客戶端和服務器端就能夠開始傳送數據。以上就是TCP三次握手的整體介紹。server

那四次揮手呢?blog

當客戶端和服務器經過三次握手創建了TCP鏈接之後,當數據傳送完畢,確定是要斷開TCP鏈接的啊。那對於TCP的斷開鏈接,這裏就有了神祕的「四次揮手」。資源

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

2.第二次揮手:主機2收到了主機1發送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number爲Sequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我也沒有數據要發送了,能夠進行關閉鏈接了;原理

3.第三次揮手:主機2向主機1發送FIN報文段,請求關閉鏈接,同時主機2進入CLOSE_WAIT狀態;cli

4.第四次揮手:主機1收到主機2發送的FIN報文段,向主機2發送ACK報文段,而後主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段之後,就關閉鏈接;此時,主機1等待2MSL後依然沒有收到回覆,則證實Server端已正常關閉,那好,主機1也能夠關閉鏈接了。

至此,TCP的四次揮手就這麼愉快的完成了。當你看到這裏,你的腦子裏會有不少的疑問,不少的不懂,感受很凌亂;沒事,咱們繼續總結。

爲何要三次握手?

既然總結了TCP的三次握手,那爲何非要三次呢?怎麼以爲兩次就能夠完成了。那TCP爲何非要進行三次鏈接呢?在謝希仁的《計算機網絡》中是這樣說的:

爲了防止已失效的鏈接請求報文段忽然又傳送到了服務端,於是產生錯誤。

在書中同時舉了一個例子,以下:

"已失效的鏈接請求報文段」的產生在這樣一種狀況下:client發出的第一個鏈接請求報文段並無丟失,

而是在某個網絡結點長時間的滯留了,以至延誤到鏈接釋放之後的某個時間纔到達server。原本這是一

個早已失效的報文段。但server收到此失效的鏈接請求報文段後,就誤認爲是client再次發出的一個新

的鏈接請求。因而就向client發出確認報文段,贊成創建鏈接。假設不採用「三次握手」,那麼只要server

發出確認,新的鏈接就創建了。因爲如今client並無發出創建鏈接的請求,所以不會理睬server的確認,

也不會向server發送數據。但server卻覺得新的運輸鏈接已經創建,並一直等待client發來數據。這樣,

server的不少資源就白白浪費掉了。採用「三次握手」的辦法能夠防止上述現象發生。例如剛纔那種狀況,

client不會向server的確認發出確認。server因爲收不到確認,就知道client並無要求創建鏈接。"

這就很明白了,防止了服務器端的一直等待而浪費資源。

爲何要四次揮手?

那四次揮手又是爲什麼呢?TCP協議是一種面向鏈接的、可靠的、基於字節流的運輸層通訊協議。TCP是全雙工 模式,這就意味着,當主機1發出FIN報文段時,只是表示主機1已經沒有數據要發送了,主機1告訴主機2, 它的數據已經所有發送完畢了;可是,這個時候主機1仍是能夠接受來自主機2的數據;當主機2返回ACK報文 段時,表示它已經知道主機1沒有數據發送了,可是主機2仍是能夠發送數據到主機1的;當主機2也發送了FIN 報文段時,這個時候就表示主機2也沒有數據要發送了,就會告訴主機1,我也沒有數據要發送了,以後彼此 就會愉快的中斷此次TCP鏈接。若是要正確的理解四次揮手的原理,就須要瞭解四次揮手過程當中的狀態變化。

FIN_WAIT_1: 這個狀態要好好解釋一下,其實FIN_WAIT_1和FIN_WAIT_2狀態的真正含義都是表示等 待對方的FIN報文。而這兩種狀態的區別是:FIN_WAIT_1狀態其實是當SOCKET在ESTABLISHED狀態時, 它想主動關閉鏈接,向對方發送了FIN報文,此時該SOCKET即進入到FIN_WAIT_1狀態。而當對方迴應ACK報 文後,則進入到FIN_WAIT_2狀態,固然在實際的正常狀況下,不管對方何種狀況下,都應該立刻迴應ACK 報文,因此FIN_WAIT_1狀態通常是比較難見到的,而FIN_WAIT_2狀態還有時經常能夠用netstat看到。 (主動方)

FIN_WAIT_2:上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2狀態下的SOCKET,表示半鏈接,也即 有一方要求close鏈接,但另外還告訴對方,我暫時還有點數據須要傳送給你(ACK信息),稍後再關閉鏈接。 (主動方)

CLOSE_WAIT:這種狀態的含義實際上是表示在等待關閉。怎麼理解呢?當對方close一個SOCKET後發送FIN 報文給本身,你係統毫無疑問地會迴應一個ACK報文給對方,此時則進入到CLOSE_WAIT狀態。接下來呢,實 際上你真正須要考慮的事情是察看你是否還有數據發送給對方,若是沒有的話,那麼你也就能夠 close這個 SOCKET,發送FIN報文給對方,也即關閉鏈接。因此你在CLOSE_WAIT狀態下,須要完成的事情是等待你去關 閉鏈接。(被動方)

LAST_ACK: 這個狀態仍是比較容易好理解的,它是被動關閉一方在發送FIN報文後,最後等待對方的ACK報 文。當收到ACK報文後,也便可以進入到CLOSED可用狀態了。(被動方)

TIME_WAIT: 表示收到了對方的FIN報文,併發送出了ACK報文,就等2MSL後便可回到CLOSED可用狀態了。 若是FINWAIT1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,能夠直接進入到TIME_WAIT狀態,而無 須通過FIN_WAIT_2狀態。(主動方)

CLOSED: 表示鏈接中斷。

相關文章
相關標籤/搜索