三次握手與四次斷開

[TOC]

TCP是一種面向連接的單播協議,在發送數據前,通訊雙方必須在彼此間建立一條連接。所謂的「連接」,其實是客戶端和伺服器的記憶體里保存的一份關於對方的資訊,如ip地址、埠號等。

一、三次握手

三次握手的過程

TCP 三次握手就好比兩個人在街上隔著50米看見了對方,但是因為霧霾等原因不能100%確認,所以要通過招手的方式相互確定對方是否認識自己。

簡單的比喻

張三首先向李四招手(syn),李四看到張三向自己招手後,向對方點了點頭擠出了一個微笑(ack)。張三看到李四微笑後確認了李四成功辨認出了自己(進入estalished狀態)。

但是李四還有點狐疑,向四周看了一看,有沒有可能張三是在看別人呢,他也需要確認一下。所以李四也向張三招了招手(syn),張三看到李四向自己招手後知道對方是在尋求自己的確認,於是也點了點頭擠出了微笑(ack),李四看到對方的微笑後確認了張三就是在向自己打招呼(進入established狀態)。

於是兩人加快步伐,走到了一起,相互擁抱。

為什麼是三次

過程:張三招手–李四點頭微笑–李四招手–張三點頭微笑 。其中李四連續進行了2個動作,先是點頭微笑(回復對方),然後再次招手(尋求確認),實際上可以將這兩個動作合一,招手的同時點頭和微笑(syn+ack)。於是四個動作就簡化成了三個動作,張三招手–李四點頭微笑並招手–張三點頭微笑。這就是三次握手的本質,中間的一次動作是兩個動作的合併。

圖的解釋:

  1. client端發送syn欄位,請求連接
  2. server端回復acksyn欄位欄位確定與之連接
  3. client接到確認後進入established已建立狀態,並發送ack欄位確認對方的連接

為什麼要三次握手

「3次握手」的作用就是雙方都能明確自己和對方的收、發能力是正常的

  1. 第一次 客戶端發送網路包,伺服器收到了。這樣伺服器得出結論:客戶端的發送能力、服務端的接收能力是正常的。
  2. 第二次 服務端發包,客戶端收到了。此時客戶端得出結論:服務端的接收、發送能力正常,客戶端的接收、發送能力正常
  3. 第三次 客戶端發送的包,服務端收到了。這樣服務端就能得出結論:服務端的接收、發送能力正常,客戶端的接收、發送能力正常

每次握手確認的能力 | | 客戶端 | 服務端 | | —————- | ———- | ———- | | 第一次(伺服器) | 發送 | 接收 | | 第二次(客戶端) | 接收、發送 | 接收、發送 | | 第三次(服務端) | 接收、發送 | 接收、發送 | 客戶端與服務端能力確認 | 視角 | 客戶端接收能力 | 客戶端發送能力 | 服務端接收能力 | 服務端發送能力 | | —— | ————– | ————– | ————– | ————– | | 客戶端 | 二 | 一+二 | 一+二 | 二 | | 服務端 | 二+三 | 一 | 一 | 二+三 |

二、四次斷開

四次斷開過程

TCP斷開鏈接的過程和建立鏈接的過程比較類似,只不過中間的兩部並不總是會合成一步走,所以它分成了4個動作,張三揮手(fin)——李四傷感地微笑(ack)——李四揮手(fin)——張三傷感地微笑(ack)。

  1. 客戶端發送FIN欄位,客戶端進入fin_wait 狀態,服務端進入close_wait狀態
  2. 服務端回復ACK欄位,客戶端進入fin_wait狀態
  3. 服務端再次發送FIN欄位,服務端並進入last_wait狀態
  4. 客戶端確認,回復ACK欄位,客戶端進入time_wait[1]狀態,服務端進入關閉狀態

為什麼是四次

  • 握手 服務端在LINSTEN狀態下,收到建立請求的報文後,把ACKSYN放在一個報文里發送。
  • 斷開 當接收到對方的FIN報文後,僅僅表示對方不在發送數據了,但是還能接收。己方是否關閉發送通道,需要上層應用來決定。

  1. 它是主動關閉的一方在回復完對方的揮手後進入的一個長期狀態,這個狀態標準的持續時間是4分鐘,4分鐘後才會進入到closed狀態,釋放套接字資源。不過在具體實現上這個時間是可以調整的。它就好比主動分手方要承擔的責任,是你提出的要分手,你得付出代價。這個後果就是持續4分鐘的time_wait狀態,不能釋放套接字資源(埠),就好比守寡期,這段時間內套接字資源(埠)不得回收利用。 ↩︎