1、TCP三次握手網絡
第一次握手:Client 將標誌位 SYN=1 ,隨機產生一個值 seq=J ,並將該數據包發送給 Server 。此時,Client 進入SYN_SENT 狀態,等待 Server 確認。
第二次握手:Server 收到數據包後由標誌位 SYN=1 知道Client請求創建鏈接,Server 將標誌位 SYN 和 ACK 都置爲 1 ,ack=J+1,隨機產生一個值 seq=K ,並將該數據包發送給 Client 以確認鏈接請求,Server 進入 SYN_RCVD 狀態。此時,Server 進入 SYC_RCVD 狀態。
第三次握手:Client 收到確認後,檢查 ack 是否爲 J+1 ,ACK 是否爲 1 。
若是正確,則將標誌位 ACK 置爲 1 ,ack=K+1 ,並將該數據包發送給 Server 。此時,Client 進入 ESTABLISHED 狀態。
Server 檢查 ack 是否爲 K+1 ,ACK 是否爲 1 ,若是正確則鏈接創建成功。此時 Server 進入 ESTABLISHED 狀態,完成三次握手,隨後 Client 與 Server 之間能夠開始傳輸數據了。
Client 和 Server 互相作了一次 SYNC 和 ACK 。spa
問題:TCP爲何須要三次握手,爲何不是兩次?3d
爲了防止已失效的鏈接請求報文忽然又傳送到了服務端,於是產生錯誤。
客戶端發出的鏈接請求報文並未丟失,而是在某個網絡節點長時間滯留了,以至延誤到連接釋放之後的某個時間纔到達 Server 。code
若不採用「三次握手」,那麼只要 Server 發出確認數據包,新的鏈接就創建了。因爲 Client 此時並未發出創建鏈接的請求,因此其不會理睬 Server 的確認,也不與 Server 通訊;而這時 Server 一直在等待 Client 的請求,這樣 Server 就白白浪費了必定的資源。
若採用「三次握手」,在這種狀況下,因爲 Server 端沒有收到來自客戶端的確認,則就會知道 Client 並無要求創建請求,就不會創建鏈接。
2、TCP四次揮手server
第一次揮手:Client 發送一個 FIN=M ,用來關閉 Client 到 Server 的數據傳送。此時,Client 進入 FIN_WAIT_1 狀態。 第二次揮手,Server 收到 FIN 後,發送一個 ACK 給 Client ,確認序號爲 M+1(與 SYN 相同,一個 FIN 佔用一個序號)。此時,Server 進入 CLOSE_WAIT 狀態。注意,TCP 連接處於半關閉狀態,即客戶端已經沒有要發送的數據了,但服務端若發送數據,則客戶端仍要接收。 第三次揮手,Server 發送一個 FIN=N ,用來關閉 Server 到 Client 的數據傳送。此時 Server 進入 LAST_ACK 狀態。 第四次揮手,Client 收到 FIN 後,此時 Client 進入 TIME_WAIT 狀態。接着,Client 發送一個 ACK 給 Server ,確認序號爲 N+1 。Server 接收到後,此時 Server 進入 CLOSED 狀態,完成四次揮手。
問題:TCP爲何須要四次揮手?blog
首先TCP 是全雙工模式,須要雙向都斷開鏈接。
當主機 1 發出 FIN
報文段時,只是表示主機 1 已經沒有數據要發送了,主機 1 告訴主機 2 ,它的數據已經所有發送完畢了;可是,這個時候主機 1 仍是能夠接受來自主機 2 的數據;資源
當主機 2 返回 ACK
報文段時,表示它已經知道主機 1 沒有數據發送了,可是主機 2 仍是能夠發送數據到主機 1 的。class
由於主機 2 此時可能還有數據想要發送給主機 1 ,因此揮手不能像握手只有三次,而是多了那麼「一次」!cli
當主機 2 也發送了 FIN
報文段時,這個時候就表示主機 2 也沒有數據要發送了,就會告訴主機 1 ,我也沒有數據要發送了,以後彼此就會愉快的中斷此次 TCP 鏈接。請求
問題:爲何須要TIME_WAIT?
由於在第四步的時候,client發送的ACK可能丟失並致使server從新發送FIN消息,TIME_WAIT維護鏈接狀態.若是執行主動關閉的一方client不進入到TIME_WAIT狀態就關閉鏈接那會發生什麼呢?當重傳的FIN消息到達時,由於TCP已經再也不有鏈接的信息了,因此就用RST(從新啓動)消息應答,致使server進入錯誤的狀態而不是有序終止狀態,若是發送最後ACK消息的一方處於TIME_WAIT狀態並仍然記錄着鏈接的信息,它就能夠正確的響應對等方server的FIN消息了.