tcp状态机-三次握手-四次挥手以及常见面试题
TCP狀態機介紹
在網絡協議棧中,目前只有TCP提供了一種面向連接的可靠性數據傳輸。而可靠性,無非就是保證,我發給你的,你一定要收到。確保中間的通信過程中,不會丟失數據和亂序。在TCP保證可靠性數據傳輸的實現來看,超時重傳、序列號及數據的應答 這三個特征 就是實現可靠性的最基本保證,而對于tcp窗口大小等等設置,也是保證可靠性的一個方面。所有的目的只為一個,保證傳輸數據的完整性。為了解決傳輸線路的不穩定性造成數據包的丟失情況,tcp 使用了發送方超時重傳和接收方數據應答的策略。概括而言,就是一種“狀態協議“,保證通信雙方數據收發的一致性。
三次握手
三次握手過程
三次握手過程是客戶端主動向正在監聽的服務發起交換序號、建立連接的過程,三次握手過程如下:
客戶端主動發送SYN包到服務器,其中包含客戶端的初始序號seq=x,并進入SYN_SENT狀態,等待服務器確認。(其中,SYN=1,ACK=0,表示這是一個TCP連接請求數據報文;序號seq=x,x是隨機數,表明傳輸數據時的第一個數據字節的序號是x)。
服務器收到請求后,必須確認客戶的數據包,同時自己也發送一個SYN包,即SYN+ACK包,此時服務器進入SYN_RECV狀態。(其中確認報文段中,標識位SYN=1,ACK=1,表示這是一個TCP連接響應數據報文,并含服務端的初始序號seq=y,y是隨機數,以及服務器對客戶端初始序號的確認號ack(服務器)=seq(客戶端)+1=x+1)。
客戶端收到服務器的SYN+ACK包,向服務器發送確認包(seq=x+1,ack=y+1),此包發送完畢,客戶端和服務器進入ESTAB_LISHED(TCP連接成功)狀態,完成三次握手。
三次握手交換各自的序號,建立起連接。
握手過程為什么是三次而不是兩次、四次?
TCP作為一種可靠傳輸控制協議,其核心思想:既要保證數據可靠傳輸,又要提高傳輸的效率,而用三次恰恰可以滿足以上兩方面的需求!
為了實現可靠數據傳輸, TCP 協議的通信雙方, 都必須維護一個序列號, 以標識發送出去的數據包中, 哪些是已經被對方收到的。 三次握手的過程即是通信雙方相互告知序列號起始值, 并確認對方已經收到了序列號起始值的必經步驟
兩次握手的場景
兩次握手過程其實只有三次握手的前兩次握手,沒有第三次握手
兩次握手至多只有連接發起方的起始序列號能被確認, 另一方選擇的序列號則得不到確認。
想象一個場景,client向server發送一個連接請求,由于一些原因,導致client發出的連接請求在一個網絡節點逗留了比較多的時間。此時client會將此連接請求作為無效處理 又重新向server發起了一次新的連接請求,server正常收到此連接請求后建立了連接,數據傳輸完成后釋放了連接。如果此時client發出的第一次請求又到達了server,server會以為client又發起了一次連接請求。如果是兩次握手:此時連接就建立了,server會維持連接一直等待client發送數據,從而白白浪費server的資源。 如果是三次握手:由于client沒有發起連接請求,也就不會理會server的連接響應,server沒有收到client的確認連接,就會關閉掉本次連接。如果第一次握手大量延時或者第二次握手大量丟失 ,就會造成“SYN的洪水攻擊”效果。
四次握手的場景
四次握手其實就是將第二次握手發送ACK與SYN分開進行,這樣子有違高效的原則。
序列號與確認號
- wireshark中序列號默認顯示相對序列號,序列號是從0開始,實際序列號是在三次握手過程雙方隨機選取的。可以通過設置來顯示真實的序列號,【編輯】->【首選項】->【Protocols】->【TCP】->【Relative sequence numbers(Requires “Analyer TCP sequence numbers”)】復選框去掉
- 通過流量圖來分析序列號與確認號。【統計】->【流量圖】->【流類型】選擇【TCP Flows】
通過HTTP請求的TCP流量圖分析序列號與確認號
四次揮手
四次揮手主要是關閉tcp建立起來的連接,釋放相關資源
四次揮手過程
在實際應用中,客戶端主動關閉到服務器的連接,服務器在檢測到客戶端關閉連接后,關閉對應的連接。
- 第一次揮手: 客戶端發送一個FIN,用來關閉客戶端到服務器的數據傳送服務器的確認。其中終止標志位FIN=1,序列號seq=u.
- 第二次揮手: 服務器收到這個FIN,它發送一個ACK,確認ack為收到的序號加一。
- 第三次揮手: 關閉服務器到客戶端的連接,發送一個FIN給客戶端。
- 第四次揮手: 客戶端收到FIN后,并發回一個ACK報文確認,并將確認序號seq設置為收到序號加一。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
客戶端發送FIN后,進入終止等待狀態,服務器收到客戶端連接釋放報文段后,就立即給客戶端發送確認,服務器就進入CLOSE_WAIT狀態,此時TCP服務器進程就通知高層應用進程,因而從客戶端到服務器的連接就釋放了。此時是“半關閉狀態”,即客戶端不可以發送給服務器,服務器可以發送給客戶端。
此時,如果服務器沒有數據報發送給客戶端,其應用程序就通知TCP釋放連接,然后發送給客戶端連接釋放數據報,并等待確認。客戶端發送確認后,進入TIME_WAIT狀態,但是此時TCP連接還沒有釋放,然后經過等待計時器設置的2MSL后,才進入到CLOSED狀態。
2.為什么需要2MSL時間?
首先,MSL即Maximum Segment Lifetime,就是最大報文生存時間,是任何報文在網絡上的存在的最長時間,超過這個時間報文將被丟棄。《TCP/IP詳解》中是這樣描述的:MSL是任何報文段被丟棄前在網絡內的最長時間。RFC 793中規定MSL為2分鐘,實際應用中常用的是30秒、1分鐘、2分鐘等。
TCP的TIME_WAIT需要等待2MSL,當TCP的一端發起主動關閉,三次揮手完成后發送第四次揮手的ACK包后就進入這個狀態,等待2MSL時間主要目的是:防止最后一個ACK包對方沒有收到,那么對方在超時后將重發第三次握手的FIN包,主動關閉端接到重發的FIN包后可以再發一個ACK應答包。在TIME_WAIT狀態時兩端的端口不能使用,要等到2MSL時間結束才可以繼續使用。當連接處于2MSL等待階段時任何遲到的報文段都將被丟棄。
3.為什么是四次揮手,而不是三次或是五次、六次?
雙方關閉連接要經過雙方都同意。所以,首先是客服端給服務器發送FIN,要求關閉連接,服務器收到后會發送一個ACK進行確認。服務器然后再發送一個FIN,客戶端發送ACK確認,并進入TIME_WAIT狀態。等待2MSL后自動關閉。
總結:
(1)為了保證客戶端發送的最后一個ACK報文段能夠到達服務器。即最后一個確認報文可能丟失,服務器會超時重傳,然后服務器發送FIN請求關閉連接,客戶端發送ACK確認。一個來回是兩個報文生命周期。
如果沒有等待時間,發送完確認報文段就立即釋放連接的話,服務器就無法重傳,因此也就收不到確認,就無法按步驟進入CLOSED狀態,即必須收到確認才能close。
(2)防止已經失效的連接請求報文出現在連接中。經過2MSL,在這個連續持續的時間內,產生的所有報文段就可以都從網絡消失。
參考
- TCP狀態機-狀態解析
- TCP 為什么三次握手而不是兩次握手(正解版)
- TCP 為什么是三次握手,而不是兩次或四次?
- TCP為什么是三次握手和四次揮手
- SDN手冊
總結
以上是生活随笔為你收集整理的tcp状态机-三次握手-四次挥手以及常见面试题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: try代码块中出现异常后try内程序会继
- 下一篇: Win7虚拟无线AP以及Android手