TCP 三次握手和四次揮手理解

三次握手建立連接

  1. 客戶主機(jī)發(fā)送請(qǐng)求報(bào)文,F(xiàn)lag設(shè)置為 SYN,帶上 Seq, 假設(shè)為 clientNo;
  2. 服務(wù)主機(jī)接收到報(bào)文后,為這次連接分配資源,并回復(fù)報(bào)文, Flag設(shè)置為 [SYN, ACK], 帶上 Seq, 假設(shè)為 serverNo,同時(shí)帶上 Ack,為clientNo + 1;
  3. 客戶主機(jī)收到報(bào)文后,為鏈接分配資源,也會(huì)發(fā)送回復(fù)報(bào)文,F(xiàn)lag設(shè)置為 ACK, 帶上 Seq,為 clientNo + 1, 并帶上 Ack,為 serverNo + 1。

三次握手后,TCP連接正式建立。具體流程如下圖所示:

三次握手

四次揮手?jǐn)嚅_(kāi)連接

  1. 客戶主機(jī)發(fā)送斷開(kāi)連接請(qǐng)求(也可以是服務(wù)主機(jī)首先發(fā)送該請(qǐng)求,如 Http 服務(wù)器),發(fā)送報(bào)文,F(xiàn)lag設(shè)置為 FIN,并帶上 Seq,假設(shè)為 clientNo。發(fā)送該報(bào)文,可以通俗的理解為:客戶主機(jī)告訴服務(wù)主機(jī),我們沒(méi)啥好說(shuō)的了,你那邊沒(méi)什么異議的話,要不我們分手吧。
  2. 服務(wù)主機(jī)收到 Fin 報(bào)文后,發(fā)送回復(fù)報(bào)文,F(xiàn)lags設(shè)置為 ACK,帶上Seq,假設(shè)為 serverNo1,同時(shí)帶上 Ack,為clientNo + 1??梢酝ㄋ椎睦斫鉃椋何叶愕囊馑剂?,讓我先準(zhǔn)備準(zhǔn)備先。此時(shí),提出分手的主機(jī)進(jìn)入 FIN_WAIT 狀態(tài),等待服務(wù)主機(jī)的分手報(bào)文。
  3. 服務(wù)主機(jī)確定數(shù)據(jù)已經(jīng)發(fā)送完成,則向客戶主機(jī)發(fā)送斷開(kāi)報(bào)文,F(xiàn)lag設(shè)置為 FIN,并帶上 Seq,假設(shè)為 serverNo2??梢岳斫鉃椋罕坛?,我這邊事情完結(jié)了,我們可以分手了。
  4. 客戶主機(jī)收到 FIN 報(bào)文后,知道可以關(guān)閉網(wǎng)絡(luò),發(fā)送回復(fù)報(bào)文,設(shè)置Flags為 ACK,帶上Seq為clientNo2,Ack為ServerNo2 + 1,之后進(jìn)入 TIME_WAIT狀態(tài),如果 2MSL 后,服務(wù)主機(jī)沒(méi)有回應(yīng),說(shuō)明服務(wù)主機(jī)已經(jīng)正常關(guān)閉,客戶主機(jī)也關(guān)閉連接。

具體流程如下圖所示:

三次揮手

抓包實(shí)例

下圖是用 WireShark 對(duì) HTTP 請(qǐng)求的抓包實(shí)例:

WireShark抓包

前三個(gè)包是三次握手,后四個(gè)包是四次揮手

三次握手
  1. 客戶端發(fā)送 SYN 包,Seq為0
  2. 服務(wù)端發(fā)送 [SYN, ACK] 包,Seq為0, Ack為1
  3. 客戶端發(fā)送 ACK 包,Seq為0, Ack為1
四次揮手
  1. 服務(wù)端發(fā)送 [FIN, ACK] 包,Seq為1226,F(xiàn)lags中的 ACK 不是用于關(guān)閉連接
  2. 客戶端發(fā)送 ACK 包,Seq為2031, Ack為1227
  3. 客戶端發(fā)送 [FIN, ACK] 包,Seq為2031
  4. 服務(wù)端發(fā)送 ACK 包,Seq為1227, Ack=2032

注意

什么要三次握手

在謝希仁的《計(jì)算機(jī)網(wǎng)絡(luò)》中是這樣說(shuō)的:

為了防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到了服務(wù)端,因而產(chǎn)生錯(cuò)誤。

在書(shū)中同時(shí)舉了一個(gè)例子,如下:

“已失效的連接請(qǐng)求報(bào)文段”的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個(gè)連接請(qǐng)求報(bào)文段并沒(méi)有丟失,而是在某個(gè)網(wǎng)絡(luò)結(jié)點(diǎn)長(zhǎng)時(shí)間的滯留了,以致延誤到連接釋放以后的某個(gè)時(shí)間才到達(dá)server。本來(lái)這是一個(gè)早已失效的報(bào)文段。但server收到此失效的連接請(qǐng)求報(bào)文段后,就誤認(rèn)為是client再次發(fā)出的一個(gè)新的連接請(qǐng)求。于是就向client發(fā)出確認(rèn)報(bào)文段,同意建立連接。假設(shè)不采用“三次握手”,那么只要server發(fā)出確認(rèn),新的連接就建立了。由于現(xiàn)在client并沒(méi)有發(fā)出建立連接的請(qǐng)求,因此不會(huì)理睬server的確認(rèn),也不會(huì)向server發(fā)送數(shù)據(jù)。但server卻以為新的運(yùn)輸連接已經(jīng)建立,并一直等待client發(fā)來(lái)數(shù)據(jù)。這樣,server的很多資源就白白浪費(fèi)掉了。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生。例如剛才那種情況,client不會(huì)向server的確認(rèn)發(fā)出確認(rèn)。server由于收不到確認(rèn),就知道client并沒(méi)有要求建立連接?!?/p>

這就很明白了,防止了服務(wù)器端的一直等待而浪費(fèi)資源。

什么要四次握手

TCP是全雙工模式,這就意味著:

  1. 當(dāng)主機(jī)1發(fā)出FIN報(bào)文段時(shí),只是表示主機(jī)1已經(jīng)沒(méi)有數(shù)據(jù)要發(fā)送了,主機(jī)1告訴主機(jī)2,它的數(shù)據(jù)已經(jīng)全部發(fā)送完畢了;但是,這個(gè)時(shí)候主機(jī)1還是可以接受來(lái)自主機(jī)2的數(shù)據(jù);
  2. 當(dāng)主機(jī)2返回ACK報(bào)文段時(shí),表示它已經(jīng)知道主機(jī)1沒(méi)有數(shù)據(jù)發(fā)送了,但是主機(jī)2還是可以發(fā)送數(shù)據(jù)到主機(jī)1的;
  3. 當(dāng)主機(jī)2也發(fā)送了FIN報(bào)文段時(shí),這個(gè)時(shí)候就表示主機(jī)2也沒(méi)有數(shù)據(jù)要發(fā)送了,就會(huì)告訴主機(jī)1,我也沒(méi)有數(shù)據(jù)要發(fā)送了,之后彼此就會(huì)愉快的中斷這次TCP連接。

內(nèi)容來(lái)源

http://www.jellythink.com/archives/705

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容