TCP的三次握手和四次揮手

2021-12-29 19:41:13 字數 4136 閱讀 3295

tcp協議屬於可靠的傳輸層協議,提供可靠的位元組流服務,採用三次握手確認建立乙個連線。

所謂位元組流服務(byte stream service)是指,為了方便傳輸,將大塊資料分割成以報文段(segment)為單位的資料報進行管理。而可靠的傳輸服務是指,能夠把資料準確可靠的傳送給對方。

為了準確無誤的將資料送達目標處,tcp協議採用了三次握手(three-way handshaking)和四次揮手(four-way handshake)策略。用tcp協議把資料報送出去後,tcp協議會向對方確認是否成功送達。

握手過程中使用了tcp的標誌(flag)——syn(synchronize,同步)和ack(acknowledge,確認)。

傳送端首先傳送乙個帶syn標誌的資料報給對方。接收端收到後,回傳乙個帶有syn/ack標誌的資料報以示傳達確認資訊。最後,傳送端再回傳乙個帶ack標誌的資料報,代表「握手」結束。

下面用乙個簡圖先建立一下概念:

只是了解tcp三次握手的概念,是沒有卵用的,你需要去了解tcp三次握手中的一些細節,來看乙個詳細的圖。

位碼即tcp標誌位,有6種標示

syn(synchronize建立聯機)

ack(acknowledgement確認)

psh(push傳送)

fin(finish結束)

urg(urgent緊急)

sequence number(順序號碼)

acknowledge number(確認號碼)

各個狀態的意義如下:

listen-偵聽來自遠方tcp埠的連線請求;

syn_sent-在傳送連線請求後等待匹配的連線請求;

syn_receved-在收到和傳送乙個連線請求後等待對連線請求的確認;

established-代表乙個開啟的連線,資料可以傳送給使用者;

第一次握手:建立連線。客戶端傳送連線請求報文段,將syn位置為1,sequence number為x;然後,客戶端進入syn_send狀態,等待伺服器的確認;

第二次握手:伺服器收到syn報文段。伺服器收到客戶端的syn報文段,需要對這個syn報文段進行確認,設定acknowledgement number為x+1(sequence number+1);同時,自己還要傳送syn請求資訊,將syn位置為1,sequence number為y;伺服器端將上述所有資訊放到乙個報文段(即syn+ack報文段)中,一併傳送給客戶端,此時伺服器進入syn_recv狀態;

第三次握手:客戶端收到伺服器的syn+ack報文段。然後將acknowledgment number設定為y+1,向伺服器傳送ack報文段,這個報文段傳送完畢以後,客戶端和伺服器端都進入established狀態,完成tcp三次握手。

完成了三次握手,客戶端和伺服器端就可以開始傳送資料。

確認號:其數值等於傳送方的傳送序號 +1(即接收方期望接收的下乙個序列號)。

由於tcp連線是全雙工的,乙個tcp連線存在雙向的讀寫通道,因此每個方向都必須單獨進行關閉。這原則是當一方完成它的資料傳送任務後就能傳送乙個fin來終止這個方向的連線。收到乙個 fin只意味著這一方向上沒有資料流動,乙個tcp連線在收到乙個fin後仍能傳送資料。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

簡單說來是 「先關讀,後關寫」,一共需要四個階段。以客戶機發起關閉連線為例:

1.伺服器讀通道關閉

2.客戶機寫信道關閉

3.客戶機讀通道關閉

4.伺服器寫信道關閉

關閉行為是在發起方資料傳送完畢之後,給對方發出乙個fin(finish)資料段。直到接收到對方傳送的fin,且對方收到了接收確認ack之後,雙方的資料通訊完全結束,過程中每次接收都需要返回確認資料段ack。

詳細過程:

第一階段 客戶機傳送完資料之後,向伺服器傳送乙個fin資料段,序列號為i;

1.伺服器收到fin(i)後,返回確認段ack,序列號為i+1,關閉伺服器讀通道;

2.客戶機收到ack(i+1)後,關閉客戶機寫信道;

(此時,客戶機仍能通過讀通道讀取伺服器的資料,伺服器仍能通過寫信道寫資料)

第二階段 伺服器傳送完資料之後,向客戶機傳送乙個fin資料段,序列號為j;

3.客戶機收到fin(j)後,返回確認段ack,序列號為j+1,關閉客戶機讀通道;

4.伺服器收到ack(j+1)後,關閉伺服器寫信道。

這是標準的tcp關閉兩個階段,伺服器和客戶機都可以發起關閉,完全對稱。

為什麼握手是三次

那tcp為什麼非要進行三次連線呢?在謝希仁的《計算機網路》中是這樣說的:

為了防止已失效的連線請求報文段突然又傳送到了服務端,因而產生錯誤。

在書中同時舉了乙個例子,如下:

「已失效的連線請求報文段」的產生在這樣一種情況下:client發出的第乙個連線請求報文段並沒有丟失,而是在某個網路結點長時間的滯留了,以致延誤到連線釋放以後的某個時間才到達server。本來這是乙個早已失效的報文段。但server收到此失效的連線請求報文段後,就誤認為是client再次發出的乙個新的連線請求。於是就向client發出確認報文段,同意建立連線。假設不採用「三次握手」,那麼只要server發出確認,新的連線就建立了。由於現在client並沒有發出建立連線的請求,因此不會理睬server的確認,也不會向server傳送資料。但server卻以為新的運輸連線已經建立,並一直等待client發來資料。這樣,server的很多資源就白白浪費掉了。採用「三次握手」的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連線。

這就很明白了,防止了伺服器端的一直等待而浪費資源。

揮手為什麼是四次

那四次分手又是為何呢?tcp協議是一種面向連線的、可靠的、基於位元組流的運輸層通訊協議。tcp是全雙工模式,這就意味著,當主機1發出fin報文段時,只是表示主機1已經沒有資料要傳送了,主機1告訴主機2,它的資料已經全部傳送完畢了;但是,這個時候主機1還是可以接受來自主機2的資料;當主機2返回ack報文段時,表示它已經知道主機1沒有資料傳送了,但是主機2還是可以傳送資料到主機1的;當主機2也傳送了fin報文段時,這個時候就表示主機2也沒有資料要傳送了,就會告訴主機1,我也沒有資料要傳送了,之後彼此就會愉快的中斷這次tcp連線。如果要正確的理解四次分手的原理,就需要了解四次分手過程中的狀態變化。

fin_wait_1: 這個狀態要好好解釋一下,其實fin_wait_1和fin_wait_2狀態的真正含義都是表示等待對方的fin報文。而這兩種狀態的區別是:fin_wait_1狀態實際上是當socket在established狀態時,它想主動關閉連線,向對方傳送了fin報文,此時該socket即進入到fin_wait_1狀態。而當對方回應ack報文後,則進入到fin_wait_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ack報文,所以fin_wait_1狀態一般是比較難見到的,而fin_wait_2狀態還有時常常可以用netstat看到。(主動方) fin_wait_2:上面已經詳細解釋了這種狀態,實際上fin_wait_2狀態下的socket,表示半連線,也即有一方要求close連線,但另外還告訴對方,我暫時還有點資料需要傳送給你(ack資訊),稍後再關閉連線。(主動方) close_wait:這種狀態的含義其實是表示在等待關閉。怎麼理解呢?當對方close乙個socket後傳送fin報文給自己,你系統毫無疑問地會回應乙個ack報文給對方,此時則進入到close_wait狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有資料傳送給對方,如果沒有的話,那麼你也就可以 close這個socket,傳送fin報文給對方,也即關閉連線。所以你在close_wait狀態下,需要完成的事情是等待你去關閉連線。(被動方) last_ack: 這個狀態還是比較容易好理解的,它是被動關閉一方在傳送fin報文後,最後等待對方的ack報文。當收到ack報文後,也即可以進入到closed可用狀態了。(被動方) time_wait: 表示收到了對方的fin報文,並傳送出了ack報文,就等2msl後即可回到closed可用狀態了。如果finwait1狀態下,收到了對方同時帶fin標誌和ack標誌的報文時,可以直接進入到time_wait狀態,而無須經過fin_wait_2狀態。(主動方) closed: 表示連線中斷。

tcp 四次揮手 TCP的三次握手和四次揮手

三次握手 第一次握手 客戶端傳送syn包 syn x 到伺服器,並進入syn send狀態,等待伺服器確認 第二次握手 伺服器收到syn包,必須確認客戶的syn ack x 1 同時自己也傳送乙個syn包 syn y 即syn ack包,此時伺服器進入syn recv狀態 第三次握手 客戶端收到伺服...

TCP三次握手和四次揮手

一 tcp三次握手 three way handshake 1 tcp三次握手的作用 三次握手的目的是連線伺服器指定埠,建立tcp連線,並同步連線雙方的序列號和確認號並交換 tcp 視窗大小資訊。在socket程式設計中,客戶端執行connect 時,將觸發三次握手。2 tcp三次握手過程 第一步 ...

TCP三次握手和四次揮手

三次握手 四次揮手 需四次揮手原因 由於tcp的半關閉特性,tcp連線時雙全工 即資料在兩個方向上能同時傳遞 因此,每個方向必須單獨的進行關閉。這個原則就是 當一方完成它的資料傳送任務後就能傳送乙個fin來終止這個方向上的連線。當一端收到乙個fin後,它必須通知應用層另一端已經終止了那個方向的資料傳...