建立一個連接需要三次握手,而終止一個連接要經過四次揮手。
這由TCP的半關閉造成的。所謂的半關閉,其實就是TCP提供了連接的一端在結束它的發送后還能接收來自另一端數據的能力。
TCP 的連接的拆除需要發送四個包,因此稱為四次揮手(Four-way handshake),客戶端或服務器均可主動發起揮手動作。
剛開始雙方都處于 ESTABLISHED 狀態,假如是客戶端先發起關閉請求。
四次揮手的過程如下:
第一次揮手:客戶端發送一個 FIN 報文,報文中會指定一個序列號。此時客戶端處于 FIN_WAIT1 狀態。即發出連接釋放報文段(FIN=1,序號seq=u),并停止再發送數據,主動關閉TCP連接,進入FIN_WAIT1(終止等待1)狀態,等待服務端的確認。
第二次揮手:服務端收到 FIN 之后,會發送 ACK 報文,且把客戶端的序列號值 +1 作為 ACK 報文的序列號值,表明已經收到客戶端的報文了,此時服務端處于 CLOSE_WAIT 狀態。即服務端收到連接釋放報文段后即發出確認報文段(ACK=1,確認號ack=u+1,序號seq=v),服務端進入CLOSE_WAIT(關閉等待)狀態,此時的TCP處于半關閉狀態,客戶端到服務端的連接釋放??蛻舳耸盏椒斩说拇_認后,進入FIN_WAIT2(終止等待2)狀態,等待服務端發出的連接釋放報文段。
第三次揮手:如果服務端也想斷開連接了,和客戶端的第一次揮手一樣,發給 FIN 報文,且指定一個序列號。此時服務端處于 LAST_ACK 的狀態。即服務端沒有要向客戶端發出的數據,服務端發出連接釋放報文段(FIN=1,ACK=1,序號seq=w,確認號ack=u+1),服務端進入LAST_ACK(最后確認)狀態,等待客戶端的確認。
第四次揮手:客戶端收到 FIN 之后,一樣發送一個 ACK 報文作為應答,且把服務端的序列號值 +1 作為自己 ACK 報文的序列號值,此時客戶端處于 TIME_WAIT 狀態。需要過一陣子以確保服務端收到自己的 ACK 報文之后才會進入 CLOSED 狀態,服務端收到 ACK 報文之后,就處于關閉連接了,處于 CLOSED 狀態。即客戶端收到服務端的連接釋放報文段后,對此發出確認報文段(ACK=1,seq=u+1,ack=w+1),客戶端進入TIME_WAIT(時間等待)狀態。此時TCP未釋放掉,需要經過時間等待計時器設置的時間2MSL后,客戶端才進入CLOSED狀態。
收到一個FIN只意味著在這一方向上沒有數據流動。客戶端執行主動關閉并進入TIME_WAIT是正常的,服務端通常執行被動關閉,不會進入TIME_WAIT狀態。
在socket編程中,任何一方執行close()操作即可產生揮手操作。