首頁 > 軟體

TCP三次握手和四次揮手

2020-06-16 17:08:45

三次握手

TCP連線是通過三次握手來連線的。

第一次握手

當用戶端向伺服器發起連線請求時,用戶端會傳送同步序列標號SYN到伺服器,在這裡我們設SYN為m,等待伺服器確認,這時用戶端的狀態為SYN_SENT。

第二次握手

當伺服器收到用戶端傳送的SYN後,伺服器要做的是確認用戶端傳送過來的SYN,在這裡伺服器傳送確認包ACK,這裡的ACK為m+1,意思是說“我收到了你傳送的SYN了”,同時,伺服器也會向用戶端傳送一個SYN包,這裡我們設SYN為n。這時伺服器的狀態為SYN_RECV。

一句話,伺服器端傳送SYNACK兩個包。

第三次握手

用戶端收到伺服器傳送的SYNACK包後,需向伺服器傳送確認包ACK,“我也收到你傳送的SYN了,我這就給你發個確認過去,然後我們即能合體了”,這裡的ACK為n+1,傳送完畢後,用戶端和伺服器的狀態為ESTABLISH,即TCP連線成功。

在三次握手中,用戶端和伺服器端都傳送兩個包SYNACK,只不過伺服器端的兩個包是一次性發過來的,用戶端的兩個包是分兩次傳送的。

三次握手示意圖如下(純手繪,見諒見諒):

四次揮手

當A端和B端要斷開連線時,需要四次握手,這裡稱為四次揮手。

斷開連線請求可以由用戶端發出,也可以由伺服器端發出,在這裡我們稱A端向B端請求斷開連線。

第一次揮手

A端向B端請求斷開連線時會向B端傳送一個帶有FIN標記的報文段,這裡的FINFINish的意思。

第二次揮手

B端收到A傳送的FIN後,B段現在可能現在還有資料沒有傳完,所以B端並不會馬上向A端傳送FIN,而是先傳送一個確認序號ACK,意思是說“你發的斷開連線請求我收到了,但是我現在還有資料沒有發完,請稍等一下唄”。

第三次揮手

當B端的事情忙完了,那麼此時B端就可以斷開連線了,此時B端向A端傳送FIN序號,意思是這次可以斷開連線了。

第四次揮手

A端收到B端傳送的FIN後,會向B端傳送確認ACK,然後經過兩個MSL時長後斷開連線。

MSL是Maximum Segment Lifetime,最大報文段生存時間,2個MSL是報文段傳送和接收的最長時間。

四次揮手示意圖如下(純手繪,見諒見諒):

兩次握手可以麼?

TCP連線時是三次握手,那麼兩次握手可行嗎?

在《計算機網路》中是這樣解釋的:已失效的連線請求報文段”的產生在這樣一種情況下:client發出的第一個連線請求報文段並沒有丟失,而是在某個網路結點長時間的滯留了,以致延誤到連線釋放以後的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連線請求報文段後,就誤認為是client再次發出的一個新的連線請求。於是就向client發出確認報文段,同意建立連線。假設不採用“三次握手”,那麼只要server發出確認,新的連線就建立了。由於現在client並沒有發出建立連線的請求,因此不會理睬server的確認,也不會向server傳送ACK包。這樣就會白白浪費資源。

而經過三次握手,用戶端和伺服器都有應有答,這樣可以確保TCP正確連線。

為什麼TCP連線是三次,揮手確是四次?

在TCP連線中,伺服器端的SYNACK向用戶端傳送是一次性傳送的,而在斷開連線的過程中,B端向A端傳送的ACKFIN是是分兩次傳送的。因為在B端接收到A端的FIN後,B端可能還有資料要傳輸,所以先傳送ACK,等B端處理完自己的事情後就可以傳送FIN斷開連線了。

為什麼在第四次揮手後會有2個MSL的延時?

前文說到

MSL是Maximum Segment Lifetime,最大報文段生存時間,2個MSL是報文段傳送和接收的最長時間。

假定網路不可靠,那麼第四次傳送的ACK可能丟失,即B端無法收到這個ACK,如果B端收不到這個確認ACK,B端會定時向A端重複傳送FIN,直到B端收到A的確認ACK。所以這個2MSL就是用來處理這個可能丟失的ACK的。

本文永久更新連結地址http://www.linuxidc.com/Linux/2017-09/146653.htm


IT145.com E-mail:sddin#qq.com