http三次握手四次揮手


最近一直忙於看前端vue相關內容,后端相關內容沒有跟進,文章停了3周,,,哎,還是懶吧!子曰生命在於運動,該學習還是要學的,文章嘛也還是要整理滴,不扯了---
參考:
----------------------------------------------------------------------------
我們常說http協議建立連接要經過3次握手,斷開連接要4次揮手,可究竟是怎么一回事兒,為什么這么設計呢?
其實這么說是不太准確的,應該說是tcp協議建立連接要3次握手,斷開連接要4次揮手,而http是基於tcp協議的,所以通常我們也這么說而已。實際上,http才不關心tcp是幾次握手幾次揮手建立連接的呢,它只關心你連接好了沒,能不能幫我傳輸數據,如果http的底層用的不是tcp協議,也就無所謂握手跟揮手的過程了。
----------------------------------------------------------------------------
不過,既然我們日常網絡訪問的http用的是tcp,那還是看一下這個過程吧
tcp可以提供全雙工的數據流傳輸服務,全雙工說白了,就是同一時間A可以發信息給B,B也可以發消息給A,倆人同時都可以給對方發消息;半雙工就是某個時間段A可以發給B,但B不能給A,換個時間段,就反過來了;單工就是只能一個給另一個類似於汽車單行道;
建立連接過程:
1、TCP服務器進程先創建傳輸控制塊TCB,時刻准備接受客戶進程的連接請求,此時服務器就進入了LISTEN(監聽)狀態;
2、TCP客戶進程也是先創建傳輸控制塊TCB,然后向服務器發出連接請求報文,這是報文首部中的同部位SYN=1,同時選擇一個初始序列號 seq=x ,此時,TCP客戶端進程進入了 SYN-SENT(同步已發送狀態)狀態。TCP規定,SYN報文段(SYN=1的報文段)不能攜帶數據,但需要消耗掉一個序號。
3、TCP服務器收到請求報文后,如果同意連接,則發出確認報文。確認報文中應該 ACK=1,SYN=1,確認號是ack=x+1,同時也要為自己初始化一個序列號 seq=y,此時,TCP服務器進程進入了SYN-RCVD(同步收到)狀態。這個報文也不能攜帶數據,但是同樣要消耗一個序號。
4、TCP客戶進程收到確認后,還要向服務器給出確認。確認報文的ACK=1,ack=y+1,自己的序列號seq=x+1,此時,TCP連接建立,客戶端進入ESTABLISHED(已建立連接)狀態。TCP規定,ACK報文段可以攜帶數據,但是如果不攜帶數據則不消耗序號。
5、當服務器收到客戶端的確認后也進入ESTABLISHED狀態,此后雙方就可以開始通信了。
這個過程理解起來,就像兩人在喊話:
A:喂,有人嗎,我想建立連接
B:有哇,你建立吧,等你吆
A:好噠,我來啦
然后倆人就建立連接了,,,,
一定要三次握手么,兩次行不行?
這么一個場景:
  • A->B: 洞幺洞幺,我是洞拐,收到請回復,Over。
  • B->A: 洞拐洞拐,洞幺收到,Over。
請問根據以上對話判斷,
1、B是否能收到A的信息? (答案是肯定的)
2、A是否能收到B的信息? (你猜?)
tcp的核心思想是保證數據可靠傳輸,如果2次,顯然不行,但3次就一定行么?未必,可能第三次的時候網絡中斷了,然后A就認為B收到了,然后一通發消息,其實B沒收到,但這是無法完全保證的。無論握手多少次都不能滿足傳輸的絕對可靠,為了效率跟相對可靠而看,3次剛剛好,所以就3次了(正好AB相互確認了一次)。
連接斷開過程:
1、客戶端進程發出連接釋放報文,並且停止發送數據。釋放數據報文首部,FIN=1,其序列號為seq=u(等於前面已經傳送過來的數據的最后一個字節的序號加1),此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。
2、服務器收到連接釋放報文,發出確認報文,ACK=1,ack=u+1,並且帶上自己的序列號seq=v,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
3、客戶端收到服務器的確認請求后,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最后的數據)。
4、服務器將最后的數據發送完畢后,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由於在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號為seq=w,此時,服務器就進入了LAST-ACK(最后確認)狀態,等待客戶端的確認。
5、客戶端收到服務器的連接釋放報文后,必須發出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,必須經過2∗MSL(最長報文段壽命)的時間后,當客戶端撤銷相應的TCB后,才進入CLOSED狀態。
6、服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB后,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。
建立連接要3次,斷開為什么要4次呢
因為tcp是全雙工的,每個方向要單獨斷開,每個方向2次,所以4次。
一定4次嗎,3次不行么,跟建立連接一樣,服務端回復的時候順帶請求斷開不可以么?
不可以,因為客戶端請求服務端斷開的時候,客戶端向服務端發送數據的這個方向已經沒有數據要發送了,但服務端可能仍有信息往客戶端發送,需要的時間不好確定,不能一直不回復讓客戶端等着,只能先回復一個,讓客戶端斷掉,然后服務端把數據發送完了之后再斷掉服務端到客戶端方向的連接;
為什么客戶端最后還要等待2MSL?
MSL(Maximum Segment Lifetime),TCP允許不同的實現可以設置不同的MSL值。
第一,保證客戶端發送的最后一個ACK報文能夠到達服務器,因為這個ACK報文可能丟失,站在服務器的角度看來,我已經發送了FIN+ACK報文請求斷開了,客戶端還沒有給我回應,應該是我發送的請求斷開報文它沒有收到,於是服務器又會重新發送一次,而客戶端就能在這個2MSL時間段內收到這個重傳的報文,接着給出回應報文,並且會重啟2MSL計時器。
第二,防止類似與“三次握手”中提到了的“已經失效的連接請求報文段”出現在本連接中。客戶端發送完最后一個確認報文后,在這個2MSL時間中,就可以使本連接持續的時間內所產生的所有報文段都從網絡中消失。這樣新的連接中不會出現舊連接的請求報文。
等待2MSL就一定能確認沒問題么?
不,還有一個超時機制,超時了,即使沒收到回復也會關閉連接。整個關閉過程如下:
 tcp關閉連接狀態轉換
上圖是tcp連接主動關閉端的狀態轉換圖:
(1)應用層調用close函數發起關閉連接請求
(2)發送FIN到對端,關閉寫通道,自己進入FIN_WAIT1狀態
(3)等待對端的確認ACK到來,接受到ACK后進入FIN_WAIT2狀態;如果在超時時間內沒有收到確認ACK直接進入CLOSED狀態
(4)如果在FIN_WAIT1狀態時收到了對端的FIN則進入CLOSING狀態(雙發都發出了關閉連接請求)
(5)在FIN_WAIT2接受到了對端FIN后進入TIME_WAIT狀態;如果在超時時間內沒有收這個FIN則直接進入CLOSED狀態
(6)在TIME_WAIT狀態等待2個MSL(2個報文最長存活周期)后進入CLOSED狀態
----------------------------------------------------------------------------
為啥3次,為啥4次,多了或者少了行不行,為什么還要等待,不等待會有什么結果,怎么盡量確定通信可靠,斷開的時候怎么確定對面也斷開了不要一直等着浪費資源,,,,嗯,差不多都解決了,over
 


免責聲明!

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



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