1. 程式人生 > >TCP--三次握手

TCP--三次握手

  我們再說TCP的時候經常會說他是有連線的,可靠的,面向資料流的三個特點,今天我們就來介紹一下TCP的有連線的。

  先說一下什麼是面向連線的,我們在建立TCP連線的時候和UDP不一樣,我們得先向客戶端傳送請求,然後客戶端回覆我們一個確認應答和請求,之後我們再給客戶端傳送確認應答,也就是經典的三次握手,這時候雙方才可以傳送資料,UDP不管你有沒有連線,上來就直接發,這就好比我們TCP用的是手機來發簡訊,當小藍想給小紅聊天的時候就給小紅髮簡訊,小紅在嗎我是小藍我想和你聊天,這時候小藍不是這條簡訊有沒有發到,他不知道自己手機是不是欠費了,他就得等著小紅的迴應,當小紅收到資訊之後,會明白,哦小藍想和我聊天,那我的手機收簡訊沒問題的,我回復他一個:我是小紅我收到了,你能看到我的訊息嗎?這時候小紅清楚自己能夠收簡訊,但是不知道自己能不能發啊,等會小藍看到了小紅的回信,這時候小藍清楚了,我的傳送功能沒問題,傳送出去了,小紅看到了,並且我的接受也沒問題,小紅給我的回信我也接受到了,但是小紅現在還在等著啊,他不知道自己是不是成功發出來訊息了,這時候小藍再回復小紅一個,沒問題我能看到你的訊息,當小紅收到的時候那這時候雙方都能清楚自己收發功能都沒問題,這時候雙方就可以開始正式傳送訊息了。

  這就我們TCP連結的過程,把小藍變成客戶端,小紅變成服務端就可以了。這個過程也就是我們TCP大名鼎鼎的三次握手。

  

第一次握手:當我們的客戶端想和服務端傳輸資料的時候,就會向服務端傳送我們的連線請求報文,也就是把報文段裡邊的SYN位置設定為1,然後客戶端就會進入SYN_SEND狀態,然後等待服務端的確認訊息。並且這時候會把報頭裡邊的Seq也就是序列號設定成一個作業系統隨機生成的一個數字X

第二次握手:當服務端接收到我們客戶端發來的SYN報文段之後,就需要對我這個SYN請求做出回答, 然後會把報頭裡邊的ACK設定為1,並且還要把確認序號設定為剛剛傳送Seq中的X+1,並且同時,自己還要傳送一個SYN請求給客戶端,並將SYN的值變成1,然後Seq設定為作業系統隨機生成的一個Y,然後服務端把上邊的資料傳送出去,這時候服務端變成SYN_RECV狀態。

第三次握手:當客戶端收到服務端發來的報文的時候,會把ACK中的值設定成剛剛生成的Y+1,然後Seq設定為X+1和第二次握手中的值是一樣的,然後傳送給服務端,當這個資料包傳送完畢值,客戶端和服務端都會進入ESTABLISHED狀態,這時候就完成餓了三次握手。

  為什麼要有三次握手?

  1. 三次握手的目的是為了方式已經失效的連結請求報文團又傳送給了服務端,從而產生了錯誤。比如現在我們的客戶端傳送了一個請求包,說服務端那我想和你建立連結,但是這個資料包在網路裡邊傳送延遲了,客戶端都放棄了,算了現在網絡卡我先不建立連線了我先關掉吧,但是等了一會,服務端接受到了訊息,看到了這個請求,如果沒有三次握手,那麼服務端看到這個請求之後連結就建立起來了,就開始往客戶端傳送包,但是客戶端不會理你,這時候服務端很多資源就浪費掉了,但是有三次握手的話,服務端接受到之後會向客戶端傳送確認,如果客戶端沒有確認,服務端也不會建立連結的。

  2. 還有就是我上邊說到的例子,存在一種情況我們的客戶端或者服務端的傳送或者接受工功能損壞了,如果客戶端和服務端三次握手成功了,就說明客戶端和服務端的傳送和接受功能都是正常的,那麼這個時候就可以傳送資料了。

  3. 並且這裡的情況和我們上次說的可靠是相呼應的,一個請求一個應答,來保證可靠。

  4. 為什麼不能是兩次,這裡要想一種情況,假如現在你要和班裡的小女生傳紙條,如果採用兩次握手,也就是說,假如現在你給他扔了一個小紙條,聊天嗎?他沒撿到,然後你又扔了一個聊天嗎?他收到了,他說好,這時候你們聊天了,聊完之後收不聊了倆人開始上課了,但是這時候突然小女生撿到了你第一次扔的那個聊天嗎?她撿到了,然後給你回了一個聊,這就算兩次握手完成了,這時候 他再跟你扔小紙條你就收不到了,所以這種 情況下兩次握手會浪費很多資源。

   那假如說在握手過程中發生了中斷怎麼辦?

  1. 如果說在第一次握手發出的時候資料包發生了中斷,也就是說A傳送給B的SYN丟失了,A會進行超時重傳,直到B收到了A的請求

  2. 如果說第二次握手的ACK和SYN發生了中斷,那麼B也是會不斷的進行超時重傳的。一直到B收到了A的確認響應,說明A收到了這個資料包

  3. 如果A發給B的第三次握手中斷了,東西丟了A不會重新發送,超時後B會再次給A傳送SYN訊號,也就是回到了第二次握手,直到B收到了A的這個第三次握手。