TCP四次揮手原理

飛馳的蝸牛發表於2019-11-03

我們對TCP三次握手耳熟能詳,那麼你知道TCP四次揮手過程嗎?

一、前言

唐代詩人李商隱在《無題》詩中寫到:“相見時難別亦難,東風無力百花殘”,表達了自己與心愛之人相見之難、離別之苦。如果把這句詩用在形容TCP連線的建立與釋放過程,也很貼切。我們知道TCP建立連線時需要三次握手,而TCP連線釋放則需要四次揮手,是不是很像詩中描述的意境——見面很難,分開更難。 如果你還不清楚相見之難TCP三次握手過程,可以看我的上篇博文TCP三次握手原理,這樣便於你更好理解TCP四次揮手釋放連線的過程。

二、TCP四次揮手過程

TCP四次揮手指的是TCP連線釋放過程, 不同於TCP連線建立時的三次握手過程,TCP連線釋放過程更加複雜。在進入正題前,我們先回憶下TCP協議的兩個重要特點:

  • TCP協議面向連線:應用在使用TCP協議通訊時,必須要先建立TCP連線。
  • TCP連線是雙向通訊:通訊的兩端是對等的,既能傳送資料,也能接收資料,就向我們打電話時一樣,既能說也能聽。

這兩個重要特點決定了TCP連線的釋放過程。下面我們一起來看下TCP四次揮手的過程都發生了什麼。為了更好的理解,簡單的畫了下TCP四次揮手示意圖如下:

TCP四次揮手過程
TCP連線資料傳輸結束後,通訊的雙方client與server都可以選擇釋放當前TCP連線,此時client與server都處於ESTABLISHED(連線確立)狀態,TCP連線釋放從此狀態開始,我們假設是client的應用程式主動發起TCP連線釋放:

  • 第一次揮手:client向server主動傳送連線釋放報文FIN=1,seq=u),報文的首部控制位FIN=1,代表自己的資料已經傳送完畢,並且要求釋放TCP連線。序號seq=u,u的值為client前面已傳送資料的最後一個位元組序號加1,client傳送完後進入FIN-WAIT-1(終止等待1)狀態。
  • 第二次揮手:server收到client的連線釋放報文後即給出確認報文ACK=1,ack=u+1,seq=v),序號seq=v,值為server前面已傳送資料的最後一個位元組序號加1,然後server進入CLOSE-WAIT(關閉等待)狀態。==這時候client到server這個方向連線就釋放了,TCP連線處於 半關閉(half-close)狀態==,client不再傳送資料,但是server仍然可以傳送資料給client。 client收到server確認後進入FIN-WAIT-2(終止等待2)狀態,然後等待server發出連線釋放報文
  • 第三次揮手:處於CLOSE-WAIT狀態的server傳送完所有資料後,主動釋放連線,server傳送的連線釋放報文FIN=1,ACK=1,seq=W,ack=u+1),因為半關閉狀態,server可能又傳送了一些資料,所以序號的值為W,同時保持確認號ack=U+1與上次一致,傳送完畢後,server進入LAST-ACK(最後確認)狀態,等待client確認。
  • 第四次揮手:client收到server連線釋放報文後,給出確認報文(ACK=1,ack=w+1,seq=u+1),此時連線還沒釋放掉,client要時間等待計時器設定的2MSL的時間,才最終進入CLOSED狀態。時間MSL是最長報文壽命時長,RFC793建議為2分鐘,但是現在網路中,這個時間設定更小。也就是說client要等待4分鐘才能進入CLOSED狀態,開始下一個連線。

上面就是TCP連線的釋放過程,如果你覺得比較複雜可以簡單理解為這樣:

client——> server: 資料傳輸完畢,請求釋放連線!

server——> client: 收到,可以釋放連線!等我處理完畢會通知你

server——> client: 我的資料也傳送完畢!可以釋放連線

client——>server: 收到!已釋放連線,Bye
複製程式碼

三、小細節

1.為什麼client在TIME-WAIT狀態必須等待2MSL的時間?
  • 為了保證client的最後傳送的ACK報文能到達server。因為這個ACK報文可能丟失,導致處於LAST-ACK狀態的server收不到對自己釋放連線報文的確認。若是server超時重傳了這個報文,client就能在2MSL時間內收到,並且重新一次確認,並重啟2MSL計時器。
  • 防止出現“已失效的連線請求報文段”出現,2MSL時間,可以使本連線持續時間內的報文段都從網路中消失。建立下一個TCP連線時就不會出現上次舊連線請求報文段
2.如果一方突然出故障了怎麼辦?

在TCP連線建立後,client與server傳輸過程中,假設client突然出故障了,server顯然無法再收到client資料了,但是server不能白白等下去。這時TCP的保活計時器(keepalive timer)就登場了。server每收到一次client的資料,就重新設定一下計時器,時間通常是2小時,若2小時內沒有再收到client資料,server就會傳送一次探測報文段,以後每隔75分鐘傳送一次,若一連傳送10次,client都沒有任何響應,server會認為client故障了,直接關閉連線。

保活計時器

四、總結

為了更清晰看到TCP各種連線之間關係,最後附上一張TCP有限狀態機圖:

在這裡插入圖片描述

相關文章