在開發中,時不時會聽到關於HTTP的三次握手和四次揮手,在面試中也會被問道HTTP的三次握手和四次揮手,不少開發者可能都會有這這種誤解,認爲三次握手和四次揮手都是HTTP協議的,實際上,這是錯誤的。正確的來講,三次揮手與四次握手是在TCP中進行的。面試
首先Client端發送鏈接請求報文,Server段接受鏈接後回覆ACK報文,併爲此次鏈接分配資源。Client端接收到ACK報文後也向Server段發生ACK報文,並分配資源,這樣TCP鏈接就創建了。緩存
seq Sequence Number是發送數據包中的第一個字節的序列號,32位。服務器
ack Acknowledgment Number是確認序列號,32位。網絡
ACK 表示Acknowledgment Number字段有意義tcp
PSH 表示Push功能,RST表示復位TCP鏈接優化
SYN 表示SYN報文(在創建TCP鏈接的時候使用)操作系統
FIN 表示沒有數據須要發送了(在關閉TCP鏈接的時候使用)指針
Source Port是源端口,16位。cdn
Destination Port是目的端口,16位。blog
Data Offset是數據偏移,4位,該字段的值是TCP首部(包括選項)長度除以4。 [1]
標誌位: 6位,URG表示Urgent Pointer字段有意義: 經過下面的圖片,咱們來詳細分析下TCP三次握手
(1)最初兩端的TCP進程都處於CLOSED關閉狀態,A(Client)主動打開鏈接,而B(Server)被動打開鏈接。(A、B關閉狀態CLOSED——B收聽狀態LISTEN——A同步已發送狀態SYN-SENT——B同步收到狀態SYN-RCVD——A、B鏈接已創建狀態ESTABLISHED)
(2)總結三次握手過程:
起初A和B都處於CLOSED狀態——B建立TCB,處於LISTEN狀態,等待A請求——A建立TCB,發送鏈接請求(SYN=1,seq=x),進入SYN-SENT狀態——B收到鏈接請求,向A發送確認(SYN=ACK=1,確認號ack=x+1,初始序號seq=y),進入SYN-RCVD狀態——A收到B的確認後,給B發出確認(ACK=1,ack=y+1,seq=x+1),A進入ESTABLISHED狀態——B收到A的確認後,進入ESTABLISHED狀態。
TCB傳輸控制塊Transmission Control Block,存儲每個鏈接中的重要信息,如TCP鏈接表,到發送和接收緩存的指針,到重傳隊列的指針,當前的發送和接收序號。
(3)爲何A還要發送一次確認呢?能夠二次握手嗎?
(4)Server端易受到SYN攻擊?
服務器端的資源分配是在二次握手時分配的,而客戶端的資源是在完成三次握手時分配的,因此服務器容易受到SYN洪泛攻擊,SYN攻擊就是Client在短期內僞造大量不存在的IP地址,並向Server不斷地發送SYN包,Server則回覆確認包,並等待Client確認,因爲源地址不存在,所以Server須要不斷重發直至超時,這些僞造的SYN包將長時間佔用未鏈接隊列,致使正常的SYN請求由於隊列滿而被丟棄,從而引發網絡擁塞甚至系統癱瘓。
防範SYN攻擊措施:下降主機的等待時間使主機儘快的釋放半鏈接的佔用,短期受到某IP的重複SYN則丟棄後續請求。
二、四次揮手
(1)四次揮手的詳述
假設Client端發起中斷鏈接請求,也就是發送FIN報文。Server端接到FIN報文後,意思是說"我Client端沒有數據要發給你了",可是若是你還有數據沒有發送完成,則沒必要急着關閉Socket,能夠繼續發送數據。因此你先發送ACK,"告訴Client端,你的請求我收到了,可是我還沒準備好,請繼續你等個人消息"。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端肯定數據已發送完成,則向Client端發送FIN報文,"告訴Client端,好了,我這邊數據發完了,準備好關閉鏈接了"。Client端收到FIN報文後,"就知道能夠關閉鏈接了,可是他仍是不相信網絡,怕Server端不知道要關閉,因此發送ACK後進入TIME_WAIT狀態,若是Server端沒有收到ACK則能夠重傳。「,Server端收到ACK後,"就知道能夠斷開鏈接了"。Client端等待了2MSL後依然沒有收到回覆,則證實Server端已正常關閉,那好,我Client端也能夠關閉鏈接了。Ok,TCP鏈接就這樣關閉了! 經過下面的圖片,咱們來詳細分析下TCP三次握手
數據傳輸結束後,通訊的雙方均可釋放鏈接,A和B都處於ESTABLISHED狀態。(A、B鏈接創建狀態ESTABLISHED——A進入等待1狀態FIN-WAIT-1——B關閉等待狀態CLOSE-WAIT——A進入等待2狀態FIN-WAIT-2——B最後確認狀態LAST-ACK——A時間等待狀態TIME-WAIT——B、A關閉狀態CLOSED)
(2)總結四次揮手過程:
(3)爲何A在TIME-WAIT狀態必須等待2MSL的時間?(MSL最長報文段壽命Maximum Segment Lifetime,MSL=2)
緣由:1)**保證A發送的最後一個ACK報文段可以到達B。**這個ACK報文段有可能丟失,使得處於LAST-ACK狀態的B收不到對已發送的FIN+ACK報文段的確認,B超時重傳FIN+ACK報文段,而A能在2MSL時間內收到這個重傳的FIN+ACK報文段,接着A重傳一次確認,從新啓動2MSL計時器,最後A和B都進入到CLOSED狀態,若A在TIME-WAIT狀態不等待一段時間,而是發送完ACK報文段後當即釋放鏈接,則沒法收到B重傳的FIN+ACK報文段,因此不會再發送一次確認報文段,則B沒法正常進入到CLOSED狀態。
緣由:2)防止「已失效的鏈接請求報文段」出如今本鏈接中。A在發送完最後一個ACK報文段後,再通過2MSL,就可使本鏈接持續的時間內所產生的全部報文段都從網絡中消失,使下一個新的鏈接中不會出現這種舊的鏈接請求報文段。
(4)爲何鏈接的時候是三次握手,關閉的時候倒是四次握手?
(5)爲何TIME_WAIT狀態須要通過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
(6)優化,咱們能夠經過修改系統參數來優化服務器