如果不了解TCP報文的格式可以點擊這里
三次握手
第一次握手:由客戶端主動發起連接建立請求,發送資料包,將SYN置為 1 ,通常叫做發送SYN包,并且隨機產生一個值:seq = J,然后將資料包發送給服務端,客戶端進入SYN_SENT狀態,等待服務端的確認
第二次握手: 服務端收到SYN報文,對該報文進行回復,將報文的標志位SYN和ACK都置為 1 ,確認應答序號ack = J + 1,同樣隨機產生一個值seq = K,將資料報發送給客戶端,服務端進入SYN_RCVD的狀態
第三次握手: 客戶端接收到資料包之后檢查ACK是否為 1 、ack是否為J + 1,如果正確,那么將ACK位置 1 ,ACK = K + 1,然后發送給服務端,此時客戶端的狀態變為ESTABLISHED,資料報到服務端,經過同樣的檢測,如果正確,服務端也變為ESTABLISHED,此時可以正常交換資料通信
簡單的說:三次握手由客戶端發起,客戶端發送一個SYN包,服務端發送一個SYN+ACK包,客戶端再發送一個ACK包,三次握手建立成功
四次揮手

第一次揮手: 客戶端發送一個FIN包來斷開連接,并停止資料發送,客戶端進入FIN_WAIT_1狀態,
注意:TCP規定,FIN報文段即使不攜帶資料,也需要消耗掉一個序列號
第二次揮手: 服務端收到一個FIN包,回復一個ACK,確認序號需要進行加一操作,因為FIN包需要消耗一個序號,此時客戶端進入CLOSE_WAIT轉態,此時服務端依舊可以進行資料的發送,客戶端依然有資料到來是要接收的,這個狀態需要持續一段時間,這個時間就是CLOSE_WAIT狀態的持續時間,
客戶端接收到服務端的確認請求之后客戶端進入FIN_WAIT_2狀態,等待服務端發送FIN包
第三次揮手: 服務端將最后的資料都發送給客戶端,然后發送一個FIN包,隨即進入LAST_ACK狀態
第四次揮手: 客戶端收到來自服務端的FIN包,需要發出確認包,當確認包發出之后狀態變為TIME_WAIT
注意:這個時候TCP連接還沒有釋放,需要經過 2 * MSL個時間才能釋放,這個時候才進入CLOSED的狀態
服務端只要收到了來自客戶端的ACK包,就進入CLOSED的狀態
思考為什么建立連接是三次,不是 倆次?
Client發送一個SYN請求包,Server回復一個ACK確認包,這不就建立好連接了嗎?是的,這樣可以建立連接,但是并不安全,比如說這個情況:
一、Client發送了一個SYN請求報文,但是由于網路擁塞,導致SYN包在網路中滯留了很久,而Client并沒有進行一個SYN的重傳,那么這個SYN包就作廢了,而在作廢之后到到Server,Server會當做是Client發來的請求,然后回復一個ACK,此時Server認為連接建立好了,而Client收到ACK并不會理睬,Server還在等著接受資料就會浪費一定的資源,
二、當Server收到SYN包回復一個ACK之后認為連接建立成功,但是如果ACK資料報丟失,那么連接并沒有建立,只是Client單方面的認為連接建立成功了,
所以說,建立連接需要三次才能保證連接建立成功,
思考為什么揮手需要四次呢?
因為當Client發送一個FIN包斷開連接的時候,但是Server并不一定也想要斷開連接,Server會先回復一個ACK,然后繼續發送自己的資料,當Server的全部資料都發送完畢之后,會主動給Client發送一個FIN包表示,我的資料也發送完畢了,現在可以斷開連接了,收到來自Client的ACK之后,雙方進入CLOSED狀態,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291035.html
標籤:其他
