三次握手和四次揮手

2022-10-10 08:48:07 字數 3639 閱讀 6915

tcp是一種面向連線的單播協議,在傳送資料前,通訊雙方必須在彼此間建立一條連線。所謂的「連線」,其實是客戶端和伺服器的記憶體裡儲存的乙份關於對方的資訊,如ip位址、埠號等。

tcp可以看成是一種位元組流,它會處理ip層或以下的層的丟包、重複以及錯誤問題。在連線的建立過程中,雙方需要交換一些連線的引數。這些引數可以放在tcp頭部。

tcp提供了一種可靠、面向連線、位元組流、傳輸層的服務,採用三次握手建立乙個連線。採用4次揮手來關閉乙個連線。

在了解了建立連線、關閉連線的「三次握手和四次揮手」後,我們再來看下tcp相關的東西。

當tcp接收到另一端的資料時,它會傳送乙個確認,但這個確認不會立即傳送,一般會延遲一會兒。ack是累積的,乙個確認位元組號n的ack表示所有直到n的位元組(不包括n)已經成功被接收了。這樣的好處是如果乙個ack丟失,很可能後續的ack就足以確認前面的報文段了。

乙個完整的tcp連線是雙向和對稱的,資料可以在兩個方向上平等地流動。給上層應用程式提供一種雙工服務。一旦建立了乙個連線,這個連線的乙個方向上的每個tcp報文段都包含了相反方向上的報文段的乙個ack。

序列號的作用是使得乙個tcp接收端可丟棄重複的報文段,記錄以雜亂次序到達的報文段。因為tcp使用ip來傳輸報文段,而ip不提供重複消除或者保證次序正確的功能。另一方面,tcp是乙個位元組流協議,絕不會以雜亂的次序給上層程式傳送資料。因此tcp接收端會被迫先保持大序列號的資料不交給應用程式,直到缺失的小序列號的報文段被填滿。

源埠和目的埠在tcp層確定雙方程序,序列號表示的是報文段資料中的第乙個位元組號,ack表示確認號,該確認號的傳送方期待接收的下乙個序列號,即最後被成功接收的資料位元組序列號加1,這個字段只有在ack位被啟用的時候才有效。

當新建乙個連線時,從客戶端傳送到服務端的第乙個報文段的syn位被啟用,這稱為syn報文段,這時序列號字段包含了在本次連線的這個方向上要使用的第乙個序列號,即初始序列號isn,之後傳送的資料是isn加1,因此syn位字段會消耗乙個序列號,這意味著使用重傳進行可靠傳輸。而不消耗序列號的ack則不是。

頭部長度(圖中的資料偏移)以32位字為單位,也就是以4bytes為單位,它只有4位,最大為15,因此頭部最大長度為60位元組,而其最小為5,也就是頭部最小為20位元組(可變選項為空)。

ack —— 確認,使得確認號有效。

rst —— 重置連線(經常看到的reset by peer)就是此字段搞的鬼。

syn —— 用於初如化乙個連線的序列號。

fin —— 該報文段的傳送方已經結束向對方傳送資料。

當乙個連線被建立或被終止時,交換的報文段只包含tcp頭部,而沒有資料。

三次握手和四次揮手的狀態轉換如下圖。

換個易於理解的視角來看為什麼要3次握手。

客戶端和服務端通訊前要進行連線,「3次握手」的作用就是雙方都能明確自己和對方的收、發能力是正常的

第一次握手:客戶端傳送網路包,服務端收到了。這樣服務端就能得出結論:客戶端的傳送能力、服務端的接收能力是正常的。

第二次握手:服務端發包,客戶端收到了。這樣客戶端就能得出結論:服務端的接收、傳送能力,客戶端的接收、傳送能力是正常的。

從客戶端的視角來看,我接到了服務端傳送過來的響應資料報,說明服務端接收到了我在第一次握手時傳送的網路包,並且成功傳送了響應資料報,這就說明,服務端的接收、傳送能力正常。而另一方面,我收到了服務端的響應資料報,說明我第一次傳送的網路包成功到達服務端,這樣,我自己的傳送和接收能力也是正常的。

第三次握手:客戶端發包,服務端收到了。這樣服務端就能得出結論:客戶端的接收、傳送能力,服務端的傳送、接收能力是正常的。

第一、二次握手後,服務端並不知道客戶端的接收能力以及自己的傳送能力是否正常。而在第三次握手時,服務端收到了客戶端對第二次握手作的回應。從服務端的角度,我在第二次握手時的響應資料傳送出去了,客戶端接收到了。所以,我的傳送能力是正常的。而客戶端的接收能力也是正常的。

經歷了上面的三次握手過程,客戶端和服務端都確認了自己的接收、傳送能力是正常的。之後就可以正常通訊了。

每次都是接收到資料報的一方可以得到一些結論,傳送的一方其實沒有任何頭緒。我雖然有發包的動作,但是我怎麼知道我有沒有發出去,而對方有沒有接收到呢?

而從上面的過程可以看到,最少是需要三次握手過程的。兩次達不到讓雙方都得出自己、對方的接收、傳送能力都正常的結論。其實每次收到網路包的一方至少是可以得到:對方的傳送、我方的接收是正常的。而每一步都是有關聯的,下一次的「響應」是由於第一次的「請求」觸發,因此每次握手其實是可以得到額外的結論的。比如第三次握手時,服務端收到資料報,表明看服務端只能得到客戶端的傳送能力、服務端的接收能力是正常的,但是結合第二次,說明服務端在第二次傳送的響應包,客戶端接收到了,並且作出了響應,從而得到額外的結論:客戶端的接收、服務端的傳送是正常的。

用**總結一下:

客收客發

服收服發

客視角二

一 + 二

一 + 二

二服視角

二 + 三一一

二 + 三

tcp連線是雙向傳輸的對等的模式,就是說雙方都可以同時向對方傳送或接收資料。當有一方要關閉連線時,會傳送指令告知對方,我要關閉連線了。這時對方會回乙個ack,此時乙個方向的連線關閉。但是另乙個方向仍然可以繼續傳輸資料,等到傳送完了所有的資料後,會傳送乙個fin段來關閉此方向上的連線。接收方傳送ack確認關閉連線。注意,接收到fin報文的一方只能回覆乙個ack, 它是無法馬上返回對方乙個fin報文段的,因為結束資料傳輸的「指令」是上層應用層給出的,我只是乙個「搬運工」,我無法了解「上層的意志」

其實3次握手的目的並不只是讓通訊雙方都了解到乙個連線正在建立,還在於利用資料報的選項來傳輸特殊的資訊,交換初始序列號isn。

3次握手是指傳送了3個報文段,4次揮手是指傳送了4個報文段。注意,syn和fin段都是會利用重傳進行可靠傳輸的。

客戶端傳送乙個syn段,並指明客戶端的初始序列號,即isn(c).

服務端傳送自己的syn段作為應答,同樣指明自己的isn(s)。為了確認客戶端的syn,將isn(c)+1作為ack數值。這樣,每傳送乙個syn,序列號就會加1. 如果有丟失的情況,則會重傳。

為了確認伺服器端的syn,客戶端將isn(s)+1作為返回的ack數值。

客戶端傳送乙個fin段,幷包含乙個希望接收者看到的自己當前的序列號k. 同時還包含乙個ack表示確認對方最近一次發過來的資料。

服務端將k值加1作為ack序號值,表明收到了上乙個包。這時上層的應用程式會被告知另一端發起了關閉操作,通常這將引起應用程式發起自己的關閉操作。

服務端發起自己的fin段,ack=k+1, seq=l

客戶端確認。ack=l+1

這是因為服務端在listen狀態下,收到建立連線請求的syn報文後,把ack和syn放在乙個報文裡傳送給客戶端。而關閉連線時,當收到對方的fin報文時,僅僅表示對方不再傳送資料了但是還能接收資料,己方是否現在關閉傳送資料通道,需要上層應用來決定,因此,己方ack和fin一般都會分開傳送。

三次握手和四次揮手

三次握手和四次揮手如圖所示 為什麼是三次握手而不是兩次 因為當客戶端第傳送syn到服務端的時候,如果有幾次請求是因為網路等原因延時等情況的時候,如果沒有第三次握手的確定。服務端就會認為客戶端重寫傳送請求了,就會去開啟連線相應。為什麼關閉連線的時候是四次握手而不是三次?當客戶端傳送請求關閉連線的時候,...

三次握手和四次揮手

tcp三次握手和四次揮手的全過程 tcp是主機對主機層的傳輸控制協議,提供可靠的連線服務,採用三次握手確認建立乙個連線 位碼即tcp標誌位,有6種表示 syn synchronous建立連線 ack acknowledgement 表示響應 確認 psh push表示有data資料傳輸 fin fi...

三次握手和四次揮手

1.在學習tcp協議的時候,總是在強調三次握手,那麼為什麼是三次?而不是兩次或者四次?強迫症表示黑人問號?今天我們就來分析一下為什麼是三次,下圖是一次tcp通訊的時序 在這個例子中,首先客戶端主動發起連線 傳送請求,然後伺服器端響應請求,然後客戶端主動關閉連線。兩條豎線表示通訊的兩端,從上到下表 示...