對於TCP/IP協議的三次握手和四次揮手的理解

因爲很久之前被老師要求講過這個問題,好久沒有看,又有些迷糊了。只能寫一篇博客來加強一下記憶

TCP報文段首部格式的幾個名詞

  1. 序列號seq:佔4個字節,用來標記數據段的順序,TCP把連接中發送的所有數據字節都編上一個序號,第一個字節的編號由本地隨機產生;給字節編上序號後,就給每一個報文段指派一個序號;序列號seq就是這個報文段中的第一個字節的數據編號。
  2.  確認號ack:佔4個字節,期待收到對方下一個報文段的第一個數據字節的序號;序列號表示報文段攜帶數據的第一個字節的編號;而確認號指的是期望接收到下一個字節的編號;因此當前報文段最後一個字節的編號+1即爲確認號。
  3. 確認ACK:佔1位,僅當ACK=1時,確認號字段纔有效。ACK=0時,確認號無效
  4. 同步SYN:連接建立時用於同步序號。當SYN=1,ACK=0時表示:這是一個連接請求報文段。若同意連接,則在響應報文段中使得SYN=1,ACK=1。因此,SYN=1表示這是一個連接請求,或連接接受報文。SYN這個標誌位只有在TCP建產連接時纔會被置1,握手完成後SYN標誌位被置0。
  5. 終止FIN:用來釋放一個連接。FIN=1表示:此報文段的發送方的數據已經發送完畢,並要求釋放運輸連接

ACK、SYN和FIN這些大寫的單詞表示標誌位,其值要麼是1,要麼是0;ack、seq小寫的單詞表示序號

三次握手過程

       1.三次握手圖片過程

      2.三次握手的文字過程

  •    (1)主機A向主機B發送TCP連接請求數據包,其中包含主機A的初始序列號seq(A)=x。(其中報文中同步標誌位SYN=1,ACK=0,表示這是一個TCP連接請求數據報文;序號seq=x,表明傳輸數據時的第一個數據字節的序號是x)
  • (2)主機B收到請求後,會發回連接確認數據包。(其中確認報文段中,標識位SYN=1,ACK=1,表示這是一個TCP連接響應數據報文,並含主機B的初始序列號seq(B)=y,以及主機B對主機A初始序列號的確認號ack(B)=seq(A)+1=x+1)
  • (3)第三次,主機A收到主機B的確認報文後,還需作出確認,即發送一個序列號seq(A)=x+1;確認號爲ack(A)=y+1的報文;

 

四次揮手過程   

   1.四次揮手的圖片過程

    

  2.四次揮手的文字過程

  • (1)第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。
  • (2)第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態。
  • (3)第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。
  • (4)第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手,連接關閉

 

問題:

1.爲什麼是三次握手而不是兩次握手或四次握手?

        簡單點來說就是兩次握手不能保證連接的穩定性,四次握手太浪費資源。

       正常情況下:A發出連接請求,但因爲丟失了,故而不能收到B的確認。於是A重新發出請求,然後收到確認,建立連接,數據傳輸完畢後,釋放連接,A發了2個,一個丟掉,一個到達,沒有“已失效的報文段”    但是,某種情況下,A的第一個在某個節點滯留了,延誤到達,本來這是一個早已失效的報文段,但是在A發送第二個,並且得到B的迴應,建立了連接以後,這個報文段竟然到達了,於是B就認爲,A又發送了一個新的請求,於是發送確認報文段,同意建立連接,假若沒有三次的握手,那麼這個連接就建立起來了(有一個請求和一個迴應),此時,A收到B的確認,但A知道自己並沒有發送建立連接的請求,因爲不會理睬B的這個確認,於是呢,A也不會發送任何數據,而B呢卻以爲新的連接建立了起來,一直等待A發送數據給自己,此時B的資源就被白白浪費了。但是採用三次握手的話,A就不發送確認,那麼B由於收不到確認,也就知道並沒有要求建立連接。所以第三次握手,主機A發送一次確認是爲了防止:如果客戶端遲遲沒有收到服務器返回的確認報文,這時他會放棄連接,重新啓動一條連接請求;但問題是:服務器不知客戶端沒收到,所以他會收到兩個連接請求,白白浪費了一條連接開銷。而四次或更多次的握手,則是浪費資源,因爲三次握手已經可以達到的效果沒有必要再去多次連接

       上次在知乎上看到一個很有意思的解釋:就說兩個人視頻通話,如果是三次握手:

         男:你聽的到嗎?

         女:我聽得到,聽得到我的聲音嗎?

         男:我聽的到你的,blablabla。。。。

       如果是兩次握手:

            男:你聽的到嗎?

            女:聽得到。

            男:你聽的到嗎?

            女:聽得到

            男:你聽得到嗎?

            女:。。。有病吧。

      如果是四次握手:

            男:你聽的到嗎?

            女:聽得到,你聽得到我說的麼。

            男:聽的到,你聽得到我說得麼。

            女:。。。。不想和傻子說話。

2.爲什麼連接的時候需要三次握手,而斷開的時候要四次揮手

      三次握手可以理解爲:

           A--請求-->B

          A<--確認--B

         A<--請求--B

         A--確認-->B

只是對於三次握手來說中間的兩個步驟是可以合併成一次的,而對於四次揮手來說則是不可以合併,因爲四次揮手發送的FIN報文僅僅表示對方不再發送數據了但是還能接收數據,所以要等自己這邊發出FIN之後,才能close。具體:

      因爲服務端在LISTEN狀態下,收到建立連接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端。而關閉連接時,當收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,己方也未必全部數據都發送給對方了,所以己方可以立即close,也可以發送一些數據給對方後,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會分開發送。

3.爲什麼client要先進入TIME-WAIT狀態,等待2MSL時間後才進入CLOSED狀態?

    爲了保證server能收到client的確認應答。 若client發完確認應答後直接進入CLOSED狀態,那麼如果該應答丟失,server等待超時後就會重新發送連接釋放請求,但此時client已經關閉了,不會作出任何響應,因此server永遠無法正常關閉。

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