java锁一次交互二次握手_Java后台开发面试实战(二):TCP三次握手四次挥手
感謝??途W網友提供的面試經驗!
1. 解釋一下TCP三次握手四次揮手
圖片來源于微信公眾號:碼農求職小助手
答: 嗯(稍作思考)…
三次握手簡單來說,在數據傳輸開始前:
第一次握手:客戶端向服務端發送一段用來連接請求的報文,其中SYN=1,ACK=0。
第二次握手:服務器端接收之后,如果同意連接。則返回一段確認的報文,SYN=1,ACK=1。
第三次握手: 客戶端收到服務端的確認后,還要再次向服務段給出確認,ACK=1。
三次握手完畢后,客戶端與服務器才正式開始傳送數據。
三次握手簡單來說,在數據傳輸開始前:
第一次握手:SYN=1(seq=x)SYN=1表示請求連接,seq=x為隨機選取序號,發送端由CLOSE進入FIN_SENT狀態。
第二次握手:ACK=1(ack=x+1),ACK=1表示確認連接,返回序列號加1是為了讓客戶端確認我接受到的信息是你發送的。SYN=1(seq=y),代表服務端也請求連接,并返回一個自己指定的序列號。服務端由LISTEN進入SYN_RECD狀態。
第三次握手:ACK=1(seq=x+1,ack=y+1)ACK=1表示確認連接;ack=y+1是為了驗證傳輸的準確性,seq=x+1(前面發送的FIN報文段需要消耗一個序號);客戶端由SYN_SENT進入ESTABLISHED階段。服務端收到ACK后進入ESTABLISH階段。
四次握手簡單來說,在數據傳輸結束后:
第一次揮手:客戶端發送一個用來關閉客戶端到服務端的數據傳送的報文。FIN=1。
第二次揮手:服務端收到FIN包后,發送一個確認包給對方,ACK=1。
第三次揮手:服務端發送一個用來關閉服務端到客戶端的數據傳送的報文,FIN=1,ACK=1。
第四次揮手:客戶端收到FIN后,發送一個確認包,ACK=1。之后等待2MSL(MSL最長報文段壽命)后,保證報文段能夠達到B,再進入關閉狀態。
至此,完成四次揮手,客戶端與服務器才正式結束數據傳輸。
四次握手詳細來說,在數據傳輸結束后:
第一次揮手:FIN=1(seq=u)FIN=1表示要求釋放連接;seq=u,u等于前面已經傳送過的數據的最后一個字節的序號加1。客戶端由由ESTABLISHED進入FIN_WAIT_1階段。
第二次揮手:ACK=1(ack=u+1,seq=v)ACK=1表明確認字段才有效;確認號為ack=u+1,seq=v,等于服務端前面已經傳送過的數據的最后一個字節的序號加1。服務端由由ESTABLISHED進入CLOSE_WAIT階段。
第三次揮手:ACK=1,FIN=1(ack=u+1,seq=w)seq=w(半關閉狀態下可能又有數據傳入)。服務端進入LAST_ACKj階段,客戶端進入FIN_WAIT_2狀態,
第四次揮手:ACK=1(ack=w+1,seq=u+1)seq=w+1(確認序號),seq=u+1(前面發送的FIN報文段需要消耗一個序號)。客戶端等待2MSL(MSL最長報文段壽命)后,保證報文段能夠達到B,進入CLOSE狀態。最后服務端收到報文后進入CLOSE之后。
二. 解釋一下SYN、ACK 、FIN 、seq和ack
同步SYN:連接建立時用于同步序號。當SYN=1,ACK=0時表示:這是一個連接請求報文段。若同意連接,則在響應報文段中使得SYN=1,ACK=1。因此,SYN=1表示這是一個連接請求,或連接接受報文。SYN這個標志位只有在TCP建產連接時才會被置1,握手完成后SYN標志位被置0。
確認ACK:占1位,僅當ACK=1時,確認號字段才有效。ACK=0時,確認號無效。
終止FIN:用來釋放一個連接。FIN=1表示:此報文段的發送方的數據已經發送完畢,并要求釋放運輸連接。
序列號seq:占4個字節,用來標記數據段的順序,TCP把連接中發送的所有數據字節都編上一個序號,第一個字節的編號由本地隨機產生;給字節編上序號后,就給每一個報文段指派一個序號;序列號seq就是這個報文段中的第一個字節的數據編號。
確認號ack:占4個字節,期待收到對方下一個報文段的第一個數據字節的序號;序列號表示報文段攜帶數據的第一個字節的編號;而確認號指的是期望接收到下一個字節的編號;因此當前報文段最后一個字節的編號+1即為確認號。
PS:ACK、SYN和FIN這些大寫的單詞表示標志位,其值要么是1,要么是0;ack、seq小寫的單詞表示序號。原文鏈接:link.
三. 為什么是三次握手,可以是兩次嗎?
不可以(非常堅定的語氣)。假如以兩次握手建立連接,服務端在某一時刻突然收到了一個來自被客戶端卡了很久已經丟棄的SYN包,服務端的操作是返回SYN+ACK并且進入工作狀態??蛻舳耸盏椒答伜?#xff0c;無法告訴服務端這是錯誤的SYN的包,會造成資源的浪費。
四. 為什么斷開連接需要四次揮手?
答:因為在客戶端發送給服務端FIN包后,服務端返回的FIN和ACK包是分開發送的。為什么要分開呢?因為客戶端發送給服務端FIN包后,只表示客戶端已經沒有數據要發送了,但是另一個方向上可能還會有數據傳輸進來。所以第二次和第三次揮手分開發送,服務端先給出ACK確認信號,表示已經收到FIN請求,然后當自己也可以結束的時候,再次發送FIN信號。是為了為未傳輸完畢的數據預留時間,所以需要揮手交互需要四次。
五. 為什么 TIME-WAIT 狀態必須等待 2MSL 的時間呢?
為了保證 A 發送的最后一個 ACK 報文段能夠到達 B。 A 發送的最后一個 ACK 報文段有可能丟失,因而使處在 LAST-ACK 狀態的 B 收不到對已發送的 FIN + ACK 報文段的確認。B 會超時重傳這個 FIN+ACK 報文段,而 A 就能在 2MSL 時間內(超時 + 1MSL 傳輸)收到這個重傳的 FIN+ACK 報文段。接著 A 重傳一次確認,重新啟動 2MSL 計時器。最后,A 和 B 都正常進入到 CLOSED 狀態。如果 A 在 TIME-WAIT 狀態不等待一段時間,而是在發送完 ACK 報文段后立即釋放連接,那么就無法收到 B 重傳的 FIN + ACK 報文段,因而也不會再發送一次確認報文段,這樣,B 就無法按照正常步驟進入 CLOSED 狀態。
防止已失效的連接請求報文段出現在本連接中。A 在發送完最后一個 ACK 報文段后,再經過時間 2MSL,就可以使本連接持續的時間內所產生的所有報文段都從網絡中消失。這樣就可以使下一個連接中不會出現這種舊的連接請求報文段。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的java锁一次交互二次握手_Java后台开发面试实战(二):TCP三次握手四次挥手的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java数组长度最大值_java 数组排
- 下一篇: java 右键卡死_为什么右键单击不适用