1. 程式人生 > >TCP協議三次握手、四次揮手詳解

TCP協議三次握手、四次揮手詳解

本文參考自文章http://blog.csdn.net/whuslei/article/details/6667471/,但文章只給了大致流程(某些部分太大略了)。這裡將詳細流程記錄下來,並添加了自己的理解。同時也在vs2012上實現了TCP在客戶端與伺服器方面的連結程式碼。程式碼可通過該網址進行下載。

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

看圖之前需要了解一下最基本的TCP連線相關用詞:

SYN:同步序列編號(Synchronize Sequence Numbers該標誌僅在三次握手建立TCP連線時有效。它提示TCP連線的服務端檢查序列編號,該序列編號為TCP連線初始端(一般是

客戶端)的初始序列編號

ACK:確認標誌

FIN:結束標誌帶有該標誌置位的資料包用來結束一個TCP回話,但對應埠仍處於開放狀態,準備接收後續資料。

一:這裡先說一下TCP的三次握手過程:【如下圖所示】

第一次握手:建立連線時,客戶端傳送SYN包。設定SYN=1,同時傳送一個校驗序列號(這裡用seq=client_isn表示)到伺服器,並進入SYN_SENT狀態,等待伺服器確認;SYN:同步序列編號(Synchronize Sequence Numbers

第二次握手伺服器收到syn包,必須確認客戶的SYN(ack=client_isn+1),同時自己也傳送一個SYN包(SYN=1,seq=server

_isn表示),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;

第三次握手客戶端收到服務器的SYN+ACK包,向伺服器傳送確認包ACK(ack=server_isn+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED(TCP連線成功)狀態,完成三次握手。

完成三次握手,客戶端與伺服器開始傳送資料

二:TCP四次揮手

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

其過程就是客戶端傳送FIN(我們分手吧),伺服器接到後就回復ACK(分吧),於此同時伺服器還會再給客戶端傳送FIN(我們分手吧),客戶端接收到資訊後回覆伺服器ACK(分吧)

三:客戶端TCP所經歷的狀態序列:【這裡可以看本文第一幅圖片,客戶端和伺服器兩條主線上標誌的狀態,而下一幅影象只是襯托

假設Client端發起中斷連線請求,也就是傳送FIN報文,進入FIN_WAIT-1狀態。Server端接到FIN報文後,意思是說"我Client端沒有資料要發給你了",但是如果你還有資料沒有傳送完成,則不必急著關閉Socket(套接字,相當於程式的介面,與外界進行通訊),可以繼續傳送資料。所以你先發送ACK,"告訴Client端,你的請求我收到了,但是我還沒準備好,請繼續你等我的訊息"。這個時候Client端就進入FIN_WAIT-2狀態,繼續等待Server端的FIN報文。當Server端確定資料已傳送完成,則向Client端傳送FIN報文,"告訴Client端,好了,我這邊資料發完了,準備好關閉連線了"。Client端收到FIN報文後,"就知道可以關閉連線了,但是他還是不相信網路,怕Server端不知道要關閉,所以傳送ACK後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。“,Server端收到ACK後,"就知道可以斷開連線了"。Client端等待了2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,我Client端也可以關閉連線了。Ok,TCP連線就這樣關閉了!

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

四:客戶端TCP所經歷的狀態序列