1. 程式人生 > 其它 >TCP/IP 3次握手和四次斷開

TCP/IP 3次握手和四次斷開

三次握手

第一次握手:建立連線。客戶端傳送連線請求報文段,將SYN位置為1,Sequence Number為x;然後,客戶端進入SYN_SEND狀態,等待伺服器的確認;

第二次握手:伺服器收到SYN報文段。伺服器收到客戶端的SYN報文段,需要對這個SYN報文段進行確認,設定Acknowledgment Number為x+1(Sequence Number+1);同時,自己自己還要傳送SYN請求資訊,將SYN位置為1,Sequence Number為y;伺服器端將上述所有資訊放到一個報文段(即SYN+ACK報文段)中,一併傳送給客戶端,此時伺服器進入SYN_RECV狀態;

第三次握手:客戶端收到伺服器的SYN+ACK報文段。然後將Acknowledgment Number設定為y+1,向伺服器傳送ACK報文段,這個報文段傳送完畢以後,客戶端和伺服器端都進入ESTABLISHED狀態,完成TCP三次握手。 

完成了三次握手,客戶端和伺服器端就可以開始傳送資料。

四次分手

當客戶端和伺服器通過三次握手建立了TCP連線以後,當資料傳送完畢,肯定是要斷開TCP連線。那對於TCP的斷開連線,這裡就有了神祕的“四次分手”。
第一次分手:主機1(可以使客戶端,也可以是伺服器端),設定Sequence Number和Acknowledgment Number,向主機2傳送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態;這表示主機1沒有資料要傳送給主機2了;

第二次分手:主機2收到了主機1傳送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number為Sequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我“同意”你的關閉請求;

第三次分手:主機2向主機1傳送FIN報文段,請求關閉連線,同時主機2進入LAST_ACK狀態;

第四次分手:主機1收到主機2傳送的FIN報文段,向主機2傳送ACK報文段,然後主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段以後,就關閉連線;
此時主機1等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那主機1也可以關閉連線了。

至此,TCP的四次分手就這麼愉快的完成了...

為什麼要四次分手

TCP協議是一種面向連線的、可靠的、基於位元組流的運輸層通訊協議。TCP是全雙工模式,這就意味著當主機1發出FIN報文段時,只是表示主機1已經沒有資料要傳送了,主機1告訴主機2,它的資料已經全部發送完畢了;但這時主機1還是可以接受來自主機2的資料;
當主機2返回ACK報文段時,表示它已經知道主機1沒有資料傳送了,但是主機2還是可以傳送資料到主機1的;
當主機2也傳送了FIN報文段時,這個時候就表示主機2也沒有資料要傳送了,就會告訴主機1,我也沒有資料要傳送了,之後彼此就會愉快的中斷這次TCP連線。如果要正確的理解四次分手的原理,就需要了解四次分手過程中的狀態變化。

FIN_WAIT_1: 這個狀態要好好解釋一下,其實FIN_WAIT_1和FIN_WAIT_2狀態的真正含義都是表示等待對方的FIN報文。
這兩種狀態的區別是:
FIN_WAIT_1狀態實際上是當SOCKET在ESTABLISHED狀態時,它想主動關閉連線而向對方傳送了FIN報文,此時該SOCKET即進入到FIN_WAIT_1狀態。
當對方迴應ACK報文後則進入到FIN_WAIT_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ACK報文,所以FIN_WAIT_1狀態一般是比較難見到的,而FIN_WAIT_2狀態還有時常常可以用netstat看到。(主動方)

FIN_WAIT_2:上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2狀態下的SOCKET表示半連線,也即有一方要求close連線,但另外還告訴對方,我暫時還有點資料需要傳送給你(ACK資訊),稍後再關閉連線。(主動方)

CLOSE_WAIT:這種狀態的含義其實是表示在等待關閉。就是當對方close一個SOCKET後傳送FIN報文給自己,你係統毫無疑問地會迴應一個ACK報文給對方,此時則進入到CLOSE_WAIT狀態。
接下來實際上你真正需要考慮的事情是察看你是否還有資料傳送給對方,如果沒有則你也就可以 close這個SOCKET,傳送FIN報文給對方,也即關閉連線。所以你在CLOSE_WAIT狀態下需要完成的事情是等待你去關閉連線。(被動方)

LAST_ACK: 這個狀態它是被動關閉一方在傳送FIN報文後,最後等待對方的ACK報文。當收到ACK報文後,也即可以進入到CLOSED可用狀態了。(被動方)

TIME_WAIT: 表示收到了對方的FIN報文,併發送出了ACK報文,就等2MSL後即可回到CLOSED可用狀態了。如果FIN_WAIT_1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入到TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。(主動方)

CLOSED: 表示連線中斷