文章目錄
- 前言
- 三次握手
- 四次揮手
- 總結
前言
關于TCP的連接配接過程,很多從事程式開發的小夥伴應該都聽過三次握手,可這三次握手的細節還是有很多人不太清楚的,特别是有些參數記不清楚,我也經常弄錯,是以我根據自己的了解畫了兩張圖,将TCP連接配接和斷開的流程簡單記錄一下,以友善後續查找複習之用。
三次握手

初始狀态:用戶端A和伺服器B均處于
CLOSED
狀态,然後伺服器B建立socket,調用監聽接口使得伺服器處于
LISTEN
狀态,等待用戶端連接配接。(後續内容用A,B簡稱代替)
- A首先向B發起連接配接,這時TCP頭部中的SYN辨別位值為1,然後標明一個初始序号
(一般是随機的),消息發送後,A進入seq=x
狀态,SYN_SENT
的封包段不能攜帶資料,但要消耗一個序号。SYN=1
- B收到A的連接配接請求後,同意建立連接配接,向A發送确認資料,這時TCP頭部中的SYN和ACK辨別位值均為1,确認序号為
,然後標明自己的初始序号ack=x+1
(一般是随機的),确認消息發送後,B進入seq=y
狀态,與連接配接消息一樣,這條消息也不能攜帶資料,同時消耗一個序号。SYN_RCVD
- A收到B的确認消息後,需要給B回複确認資料,這時TCP頭部中的ACK辨別位值為1,确認序号是
,自己的序号在連接配接請求的序号上加1,也就是ack=y+1
,此時A進入seq=x+1
狀态,當B收到A的确認回複後,B也進入ESTABLISHED
狀态,至此TCP成功建立連接配接,A和B之間就可以通過這個連接配接互相發送資料了。ESTABLISHED
四次揮手
初始狀态:用戶端A和伺服器B之間已經建立了TCP連接配接,并且資料發送完成,打算斷開連接配接,此時用戶端A和伺服器B是等價的,雙方都可以發送斷開請求,下面以用戶端A主動發起斷開請求為例。(後續内容用A,B簡稱代替)
- A首先向B發送斷開連接配接消息,這時TCP頭部中的FIN辨別位值為1,序号是
,m為A前面正常發送資料最後一個位元組序号加1得到的,消息發送後A進入seq=m
狀态,FNI_WAIT_1
的封包段不能攜帶資料,但要消耗一個序号。FIN=1
- B收到A的斷開連接配接請求需要發出确認消息,這時TCP頭部中的ACK辨別位值為1,确認号為
,而自己的序号為ack=m+1
,n為B前面正常發送資料最後一個位元組序号加1得到的,然後B進入seq=n
狀态,此時就關閉了A到B的連接配接,A無法再給B發資料,但是B仍然可以給A發資料(此處存疑),同時B端通知上方應用層,處理完成後被動關閉連接配接。然後A收到B的确認資訊後,就進入了CLOSE_WAIT
狀态。FIN_WAIT_2
- B端應用層處理完資料後,通知關閉連接配接,B向A發送關閉連接配接的消息,這時TCP頭部中的FIN和ACK辨別位值均為1,确認号
,自己的序号為ack=m+1
,(B發出确認消息後有發送了一段資料,此處存疑),消息發送後B進入seq=k
狀态。LAST_ACK
- A收到B的斷開連接配接的消息後,需要發送确認消息,這是這時TCP頭部中的ACK辨別位值為1,确認号
,序号為ack=k+1
(因為A向B發送斷開連接配接的消息時消耗了一個消息号),然後A進入m+1
狀态,若等待時間經過2MSL後,沒有收到B的重傳請求,則表明B收到了自己的确認,A進入TIME_WAIT
狀态,B收到A的确認消息後則直接進入CLOSED
狀态。至此TCP成功斷開連接配接。CLOSED
總結
- 關于三次握手,參考了很多資料說伺服器是被動打開連接配接,對此有些不解,希望知道的朋友給出提示和建議。
- 關于四次揮手,在我的叙述中有兩處存疑,就是B收到的A的主動斷開請求後,進入
狀态,是否還能發送資料到A,參考了一些資料說A不能發資料給B,但是B能發資料給A,并且A也可以接收,但是無論我在Windows環境測試還是Linux環境下測試這種狀态A都無法收到B的資料,不知道我是不是了解錯了,希望明白原理的小夥伴能解答一下。CLOSE_WAIT
- 在四次揮手的最後階段,有一個等待時間2MSL,這個不是一個時間機關,而是一個表明時間段的名詞,這段等待時間就是為了在B沒收到确認消息時,接收B的重傳請求的,如果不等待這一段時間直接進入
狀态,那麼B未收到A的确認消息就會發送重傳請求,而此時A已經關閉,就不會再給B重傳了,其中MSL的是Maximum Segment Lifetime英文的縮寫,可簡單譯為“封包最大生存時間”,也就是說如果B沒有收到确認資訊,那麼在2MSL這段時間内很大機率就會發送重傳請求,并且被A收到,RFC 793中規定MSL為2分鐘,實際應用中常用的是30秒,1分鐘和2分鐘等。CLOSED
- 在連接配接和斷開的過程都有提到
和ACK
,這一點要注意區分,大寫的ack
代表TCP頭部中6個辨別位之一,是表明這是個确認封包,而小寫的ACK
拜師确認序号,表明對方發來的資料到ack
這個序号前的都已經收到了。ack