三次握手和四次揮手理解


轉載:http://blog.csdn.net/whuslei/article/details/6667471/

TCP在傳輸之前會進行三次溝通,一般稱為“三次握手”,傳完數據斷開的時候要進行四次溝通,一般稱為“四次揮手”。

兩個序號和三個標志位:

  (1)序號:seq序號,占32位,用來標識從TCP源端向目的端發送的字節流,發起方發送數據時對此進行標記。
  (2)確認序號:ack序號,占32位,只有ACK標志位為1時,確認序號字段才有效,ack=seq+1。
  (3)標志位:共6個,即URG、ACK、PSH、RST、SYN、FIN等,具體含義如下:
  (A)URG:緊急指針(urgent pointer)有效。
  (B)ACK:確認序號有效。
  (C)PSH:接收方應該盡快將這個報文交給應用層。
  (D)RST:重置連接。
  (E)SYN:發起一個新連接。
  (F)FIN:釋放一個連接。

建立TCP需要三次握手才能建立,而斷開連接則需要四次握手。整個過程如下圖所示:

先來看看如何建立連接的。


首先Client端發送連接請求報文,Server段接受連接后回復ACK報文,並為這次連接分配資源。Client端接收到ACK報文后也向Server段發生ACK報文,並分配資源,這樣TCP連接就建立了。

那如何斷開連接呢?簡單的過程如下:

【注意】中斷連接端可以是Client端,也可以是Server端。

假設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連接就這樣關閉了!

整個過程Client端所經歷的狀態如下:

 

而Server端所經歷的過程如下:

【注意】 在TIME_WAIT狀態中,如果TCP client端最后一次發送的ACK丟失了,它將重新發送。TIME_WAIT狀態中所需要的時間是依賴於實現方法的。典型的值為30秒、1分鍾和2分鍾。等待之后連接正式關閉,並且所有的資源(包括端口號)都被釋放。

【問題1】為什么連接的時候是三次握手,關閉的時候卻是四次握手?
答:因為當Server端收到Client端的SYN連接請求報文后,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

【問題2】為什么TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可以最后一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM