TCP協議的常見面試題

閱讀本文大概需要 3 分鐘。

1. 爲什麼連接的時候是三次握手,關閉的時候卻是四次握手?

因爲當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

2. 爲什麼不能用兩次握手進行連接?

這主要是爲了防止已失效的連接請求報文段突然又傳到了B,因而產生錯誤。

現假定一種異常情況,即A發出的第一個連接請求報文段並沒有丟失,而是在某些網絡節點長時間滯留了,以致延誤到連接釋放後的某個時間纔到達B。本來這是一個早已失效的報文段。但B受到此失效的連接請求報文段後,就誤以爲是A又發出一次新的連接請求,於是就向A發出確認報文段,同意建立連接。假定不採用第三次報文握手,那麼只要B發出確認,新的連接就建立了。

由於現在A並沒有發出建立連接的請求,因此不會理睬B的確認,也不會向B發送數據,但B卻以爲新的運輸連接已經建立了,並一直等待A發來的數據。B的許多資源就這樣白白浪費了。

採用三次握手連接,可以防止上述現象的發生。例如在剛纔的異常情況下,A不會向B的確認發出確認,B由於收不到確認,就知道A並沒有要求建立連接,於是B就不會再建立連接。

640?wx_fmt=png

3. 爲什麼TIME_WAIT狀態需要經過2MSL才能返回到CLOSE狀態?

第一,爲了保證A發送的最後一個ACK報文段能夠到達B。假設網絡是不可靠的,有可以最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。在Client發送出最後的ACK回覆,但該ACK可能丟失。Server如果沒有收到ACK,將不斷重複發送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。

Client會在發送出ACK之後進入到TIME_WAIT狀態。Client會設置一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那麼Client會重發ACK並再次等待2MSL。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回覆所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那麼Client推斷ACK已經被Server成功接收,則結束TCP連接。

第二,防止“已失效的連接請求報文段”出現在本連接中。A在發送完最後一個ACK報文段後,再經過時間2MSL,就可以使本連接持續的時間內所產生的所有報文段都從網絡中消失。這樣就可以使下一個新的連接中不會出現這種舊的連接請求報文段。

4. 如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?

TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置爲2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75秒發送一次。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。


後臺回覆“加羣”,帶你進入高手如雲交流羣


推薦閱讀:


喜歡,就給我一個“在看”

640?wx_fmt=png


10T 技術資源大放送!包括但不限於:雲計算、虛擬化、微服務、大數據、網絡、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公衆號內回覆「1024」,即可免費獲取!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章