TCP三次握手四次揮手


TCP三次握手和四次揮手

1.糾正理解(重要)

首先來講一下TCP"三次握手四次揮手"來建立連接這個說法的來源,其實真正的在官方的文檔中是通過handshake這個單詞描述"整個建立-斷開連接"的過程,所以三次報文傳送建立連接和四次報文傳送斷開連接的整個過程才稱得上一次握手.

很形象的說就像我們日常生活正握手一樣,建立連接的時候相當於把手握在一起,其次我們會互相說你好,好久不見之類的話,這就像建立連接之后傳送的一些信息,最后我們互相問候之后會把握在一起的手松開,這個時候就像斷開連接,通過這樣一個詳細的握手-講話-松手例子,我們就可以清晰地理解客戶機(client)和服務器(server)從建立連接傳送信息最后再到斷開連接.

 

 

2.三報文傳送建立連接(握手)

在通過糾正理解(重要)部分之后我們可以對整個過程有了清晰的認識,下面這一部分我們專注於握手-講話-松手中的握手(建立連接)的是怎么握的.

圖一👇

圖二👇

 

 

 

我們從上往下看,

 

首先(第一步

看客戶機(client)和服務器的連接都是LISTEN(監聽)或者CLOSED(關閉)狀態。

這個無所謂了, 我們繼續向下看,握手的發起者是客戶機(client),客戶機會主動打開連接通道通過網關路由向服務器發送一條報文(SYN(SYNbit) = 1, seq = x),客戶機(client)的狀態從LISTEN(監聽)或者CLOSE(關閉)狀態(狀態1)轉換為發送同步號狀態(SYN-SENT)(狀態2)。

這條報文包含兩個部分,第一部分是SYN(同步號\同步器,反正就是同步的意思啦,這里叫做同步標志位好啦),seq(序列,就是和同步標志位一起工作的兄弟),然后它倆兄弟過千山萬水到達了服務器。

服務器監聽到了信息,打開大門接收了這倆兄弟(同步號標志位SYN=1和同步序列seq=x),這個時候服務器狀態就從LITSTEN(監聽)或者CLOSE(關閉)轉為了SYN RCVD(收到同步標志位和同步序列了)狀態。

第一個報文完成(客戶機到服務器)!

 

接着(第二步

服務器收到了客戶機請求建立連接的消息之后,選擇應答客戶機,就會發送本次應答的信息。

這個信息包括本次的SYN=1(同步標志位)和seq=y(序列y),除此之外還有ACK(應答標志位)和ack(應答數字,應答數字是接收的標志序列seq+1)同步標志位(SYNbit)和應答標志位(ACKbit)都是標志着一條消息(對應的是seq和ack或者ACKnum)是什么類型的,我們可以把SYN和ACK理解為我們寫文章時候的標題,seq和ACKnum或ack理解為文章正文。

然后客戶機收到這個回復之后,通過ack或者ACKnum(應答數字)和自己發過去的同步序列seq進行比對,發現正好ack是自己發過去的seq + 1,這樣就證明了服務器活着,並且還收到了自己發送的建立連接請求。

這個時候客戶機的狀態就從發送同步信號狀態(SYN-SENT)(狀態2)轉換成了連接建立狀態(ESTABLISHED)(狀態3)

第二個報文完成(服務器到客戶機)!

 

最后(第三步

前兩步就已經互通了,就可以建立連接了,為什么還要第三步呢?我們這里先把第三步走完,最后再單獨分析這一步,這一步也是面試中的關鍵一步!

客戶機在收到了服務器的同意信息(服務器確認信息)之后,客戶機會再一次的發送報文給客戶機,發送的內容依舊是和服務器發送回來的格式一樣,兩大部分(同步信息和標志信息),四小部分(同步號和同步序列;標志號和標志數字),為什么格式是一樣的呢?是因為從服務器發送回到客戶機和現在最后一步的目的是相同的;

服務器發送信息回到客戶機的目的是為了應答客戶機的同步信息(SYN=1和seq=x),這一步的目的同樣明顯,是為了應答服務器的同步信息(SYN=1和seq=y),我們知道了這兩條消息的目的相同,那么我們就很容易理解到,ack或者ACKnum肯定是y+1了(從服務器的seq = x + 1 推斷出來的),SYN和ACK肯定是1,我們可以發現,標志位ACK對應的的ack或者ACKnum總是收到消息的seq+1, 我們沒有推斷錯誤。

服務器收到這條消息之后呢,服務器就可以知道客戶機也還活着,並且ack活着ACKnum對應的正好是自己剛發過去的seq+1,也證明信息沒收錯(這里都是形象比喻,方便理解),這時候服務器的狀態也會從SYN RCVD轉換為ESTABLISHED。

第三步完成了(客戶機到服務器)!

 

為什么還要第三步呢

解決這個問題時,我們需要先了解一下發送報文的機制,在網絡中發送報文時會先發送第一次報文,然后有一個超時機制,超時結束后沒收到回復會再次發送一次報文,還有在網絡中我們從客戶機到服務器可以有很多的路線選擇,在了解了這兩個機制之后我們可以繼續向下分析了。

 

我們通過一種假設情況來理解為什么還需要第三步:

假如我們沒有第三步

假設我們第一次從客戶機發送報文到服務器請求連接,然后由於網絡狀況很差,我們這一個報文被阻塞在了某個路由器中,沒有送達到服務器,所以服務器就一直沒有相應我們的請求,我們客戶機超時都沒有收到服務器的反饋,接着基於我們前面講的報文發送機制可以推出,我們客戶機還會再一次發送請求報文過去,第二次發送的請求報文選擇的路線很好,瞬間到達了服務器,服務器收到后立即進行了反饋,返回了確認信息,假如沒有第三步,這時候我們連接已經建立起來了!

我們是通過超時發送的第二次報文建立的連接,如果第一次阻塞的請求這個時候路線又通了,那么服務器又收到了一次請求,服務器又立即反饋了,這個時候由於沒有第三步,到這里建立連接的兩步已經走完了,所以我們就建立了兩個連接。

現在我們有了第三步

從圖中我們看到,我們給服務器經過第三步發過去的seq是基於第一步請求的seq再+1,這樣如果被阻塞的第一次請求路線通了,服務器再次反饋回來,我們發現這個時候我們並沒有給服務器請求(超時發送第二條請求之后第一條請求我們客戶機就直接拋棄了,認為它不再有效),但是服務器怎么無緣無故又反饋了呢,基於上面沒有第三步,如果沒有第三步,到目前為止,建立連接的兩個步驟已經完成,這一步是不是服務器又給我們完成了一次建立連接,但是有了第三步,注意!我們客戶機發現是這種情況之后,就不會再執行第三步了,這樣建立連接的三步沒有執行完,所以就不能成功的再一次建立連接。這里也是面試的重點!

 

到現在為止,我們徹底明白了建立連接的整個過程,其中具體怎么樣掃描端口的啊,怎么傳輸的啊我們不需要了解,只要知道怎么個過程就可以了!當然,網絡工程師除外。

 

經過這三次報文傳送,連接已經建立好了,這樣整個"握手-說話-松手" 的 握手環節結束了,現在的狀態就是雙方手已經握在一起了。

 

 

 

 

 

3.通過建立的連接傳輸信息(交談)

這里不是我們關注的重點,略,我們看下面的四次報文松手環節!

 

 

 

 

 

4.四次報文斷開連接(松手)

 

 

在理解了三次報文建立連接之后,我們再來理解一下四次報文傳送斷開連接,通過上面的兩張圖來幫助理解,我覺得這兩張圖畫的都很好,上邊是國外畫的,我加了一些中文注釋,下邊是中文圖書上畫的。

 

下面這一部分我們專注於握手-講話-松手中的松手(斷開連接)是怎么松的.

 

第一步(客戶機請求結束到服務器):

客戶機和服務器都是連接狀態,這個時候客戶機已經不需要再發送數據到服務器了,會主動發送一個結束標志FIN和對應的序列seq,這時候客戶機就進入了FIN-WAIT-1結束等待階段1,這個時候客戶機已經不能夠再給服務器發送了,只要發了結束標志FIN就不能夠再發送數據包了,但是可以繼續接收服務器發來的數據,等下服務器也是一樣的。數據包和結束標志和應答標志是不一樣的,不能發送數據包但可以發應答標志

 

第二步(服務器反饋到客戶機):

服務器收到客戶機的斷開請求之后會給客戶機一個反饋,同樣遵循ack = seq + 1,這個返回發送之后,服務器會進入關閉等待階段CLOSE-WAIT,但是服務器仍然可以給客戶機發送數據包,因為服務器只是給客戶機發送了應答標志可應答數,這個時候服務器如果還有數據需要發送給客戶機,會繼續給客戶機發送數據,客戶機接收到服務器的應答反饋,此時客戶機從FIN-WAIT-1階段到達FIN-WAIT-2階段,如果服務器還有數據發來,仍能夠接收。

 

第三步(服務器請求結束到客戶機):

接着,服務器如果沒有數據要發給客戶機,也會向客戶機那樣請求結束,這里會有一個新的seq,專屬於服務器發來的seq是w,在服務器發送完這個結束請求之后服務器會進入到LAST-ACK階段,即等待客戶機的響應。

 

第四步(客戶機回應服務器):

最后客戶機收到服務器的請求之后,會立即給服務器回復一個確認響應,告訴服務器我知道了,但是這里客戶機按照我們的理解應該可以關閉連接了,但是並沒有,客戶機會接着進入一個時長為2MSL的等待,大概是兩個超時時間(超時就是前面建立連接時說的那個超時)。至於為什么沒有立即關閉的原因這是個面試重點,后面我會單獨介紹為什么,客戶機的回應服務器收到之后會立即關閉連接,然后客戶機的等待時間到了也會關閉連接,客戶機和服務器至此流浪各天涯!

 

為什么客戶機給服務器發送確認響應之后沒有立即關閉連接?

 因為,客戶機給服務器發送的確認響應有可能阻塞到網絡中,服務器收不到這個響應就不會關閉連接,客戶機如果沒有等待的話,客戶機關閉了,服務器就沒辦法關閉了,為了保證雙方都能夠完好的關閉,這時候客戶機選擇再等待一段時間,如果客戶機給服務器的確認響應阻塞到網路中,那么服務器等待超時之后會重新請求結束,客戶正好還沒關,就可以再一次的回復了,再回復一次給服務器,服務器這一次能收到了,就關閉了,客戶機再等待2MSL之后就可以安心關閉了。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM