TCP三次握手、四手揮手,這樣說你能明白吧!
TCP協(xié)議全稱為:Transmission Control Protocol
,是一種面向鏈接、保證數(shù)據(jù)傳輸安全、可靠的數(shù)據(jù)傳輸協(xié)議。為了確保數(shù)據(jù)的可靠傳輸,不僅需要對發(fā)出的每個(gè)字節(jié)進(jìn)行編號確認(rèn),還需要驗(yàn)證每一個(gè)數(shù)據(jù)包的有效性。每個(gè)TCP數(shù)據(jù)包是封閉在IP包中的,每個(gè)一IP包的后面緊跟著的是TCP頭,TCP報(bào)文格式如下:
源端口和目的端口字段
TCP源端口(Source Port):源計(jì)算機(jī)上的應(yīng)用程序的端口號,占 16 位。
TCP目的端口(Destination Port):目標(biāo)計(jì)算機(jī)的應(yīng)用程序端口號,占 16 位。
序列號字段
CP序列號(Sequence Number):占 32 位。它表示本報(bào)文段所發(fā)送數(shù)據(jù)的第一個(gè)字節(jié)的編號。在 TCP 連接中,所傳送的字節(jié)流的每一個(gè)字節(jié)都會(huì)按順序編號。當(dāng)SYN標(biāo)記不為1時(shí),這是當(dāng)前數(shù)據(jù)分段第一個(gè)字母的序列號;如果SYN的值是1時(shí),這個(gè)字段的值就是初始序列值(ISN),用于對序列號進(jìn)行同步。這時(shí),第一個(gè)字節(jié)的序列號比這個(gè)字段的值大1,也就是ISN加1。
確認(rèn)號字段
TCP 確認(rèn)號(Acknowledgment Number,ACK Number):占 32 位。它表示接收方期望收到發(fā)送方下一個(gè)報(bào)文段的第一個(gè)字節(jié)數(shù)據(jù)的編號。其值是接收計(jì)算機(jī)即將接收到的下一個(gè)序列號,也就是下一個(gè)接收到的字節(jié)的序列號加1。
數(shù)據(jù)偏移字段
TCP 首部長度(Header Length):數(shù)據(jù)偏移是指數(shù)據(jù)段中的“數(shù)據(jù)”部分起始處距離 TCP 數(shù)據(jù)段起始處的字節(jié)偏移量,占 4 位。其實(shí)這里的“數(shù)據(jù)偏移”也是在確定 TCP 數(shù)據(jù)段頭部分的長度,告訴接收端的應(yīng)用程序,數(shù)據(jù)從何處開始。
保留字段
保留(Reserved):占 4 位。為 TCP 將來的發(fā)展預(yù)留空間,目前必須全部為 0。
標(biāo)志位字段
CWR(Congestion Window Reduce):擁塞窗口減少標(biāo)志,用來表明它接收到了設(shè)置 ECE 標(biāo)志的 TCP 包。并且,發(fā)送方收到消息之后,通過減小發(fā)送窗口的大小來降低發(fā)送速率。
ECE(ECN Echo):用來在 TCP 三次握手時(shí)表明一個(gè) TCP 端是具備 ECN 功能的。在數(shù)據(jù)傳輸過程中,它也用來表明接收到的 TCP 包的 IP 頭部的 ECN 被設(shè)置為 11,即網(wǎng)絡(luò)線路擁堵。
URG(Urgent):表示本報(bào)文段中發(fā)送的數(shù)據(jù)是否包含緊急數(shù)據(jù)。URG=1 時(shí)表示有緊急數(shù)據(jù)。當(dāng) URG=1 時(shí),后面的緊急指針字段才有效。
ACK:表示前面的確認(rèn)號字段是否有效。ACK=1 時(shí)表示有效。只有當(dāng) ACK=1 時(shí),前面的確認(rèn)號字段才有效。TCP 規(guī)定,連接建立后,ACK 必須為 1。
PSH(Push):告訴對方收到該報(bào)文段后是否立即把數(shù)據(jù)推送給上層。如果值為 1,表示應(yīng)當(dāng)立即把數(shù)據(jù)提交給上層,而不是緩存起來。
RST:表示是否重置連接。如果 RST=1,說明 TCP 連接出現(xiàn)了嚴(yán)重錯(cuò)誤(如主機(jī)崩潰),必須釋放連接,然后再重新建立連接。
SYN:在建立連接時(shí)使用,用來同步序號。當(dāng) SYN=1,ACK=0 時(shí),表示這是一個(gè)請求建立連接的報(bào)文段;當(dāng) SYN=1,ACK=1 時(shí),表示對方同意建立連接。SYN=1 時(shí),說明這是一個(gè)請求建立連接或同意建立連接的報(bào)文。只有在前兩次握手中 SYN 才為 1。
FIN:標(biāo)記數(shù)據(jù)是否發(fā)送完畢。如果 FIN=1,表示數(shù)據(jù)已經(jīng)發(fā)送完成,可以釋放連接。
窗口大小字段
窗口大?。╓indow Size):占 16 位。它表示從 Ack Number 開始還可以接收多少字節(jié)的數(shù)據(jù)量,也表示當(dāng)前接收端的接收窗口還有多少剩余空間。該字段可以用于 TCP 的流量控制。
TCP 校驗(yàn)和字段
校驗(yàn)位(TCP Checksum):占 16 位。它用于確認(rèn)傳輸?shù)臄?shù)據(jù)是否有損壞。發(fā)送端基于數(shù)據(jù)內(nèi)容校驗(yàn)生成一個(gè)數(shù)值,接收端根據(jù)接收的數(shù)據(jù)校驗(yàn)生成一個(gè)值。兩個(gè)值必須相同,才能證明數(shù)據(jù)是有效的。如果兩個(gè)值不同,則丟掉這個(gè)數(shù)據(jù)包。Checksum 是根據(jù)偽頭 + TCP 頭 + TCP 數(shù)據(jù)三部分進(jìn)行計(jì)算的。
緊急指針字段
緊急指針(Urgent Pointer):僅當(dāng)前面的 URG 控制位為 1 時(shí)才有意義。它指出本數(shù)據(jù)段中為緊急數(shù)據(jù)的字節(jié)數(shù),占 16 位。當(dāng)所有緊急數(shù)據(jù)處理完后,TCP 就會(huì)告訴應(yīng)用程序恢復(fù)到正常操作。即使當(dāng)前窗口大小為 0,也是可以發(fā)送緊急數(shù)據(jù)的,因?yàn)榫o急數(shù)據(jù)無須緩存。
可選項(xiàng)字段
選項(xiàng)(Option):長度不定,但長度必須是 32bits 的整數(shù)倍。
TCP建立連接
TCP建立連接需要三個(gè)步驟,也就是大家熟知的三次握手。下圖了正常情形下通過三次握手建立連接的過程:
A機(jī)器發(fā)出一個(gè)數(shù)據(jù)包
SYN
設(shè)置為1,表示希望建立連接。這個(gè)包中的假設(shè)seq為x
。機(jī)器A發(fā)送`SYN`數(shù)據(jù)包后,會(huì)進(jìn)入`SYN_SENT`狀態(tài)
B機(jī)器收到A發(fā)送的
SYN
數(shù)據(jù)后,響應(yīng)一個(gè)數(shù)據(jù)包將SYN
和ACK
設(shè)置為1,假設(shè)這個(gè)響應(yīng)包的序列號為y
,同時(shí)期望下一次收到的數(shù)據(jù)庫的序列為x+1
B回復(fù)響應(yīng)包后,進(jìn)入`SYN_RECD`狀態(tài)
A收到B的響應(yīng)包后,對響應(yīng)包做應(yīng)答將
ACK
標(biāo)志設(shè)置為1,序列號為x + 1
,期望下一次收到的數(shù)據(jù)包的序列號為y+1
A機(jī)器和B機(jī)器連接建立成功
TCP三次握手抓包驗(yàn)證
以為驗(yàn)證三次握手是否描述正確,在下使用Wireshark
進(jìn)行抓包驗(yàn)證。首先使用ping
命令獲取www.baidu.com
的ip地址:
正在?Ping?www.a.shifen.com?[183.232.231.174]?具有?32?字節(jié)的數(shù)據(jù):
來自?183.232.231.174?的回復(fù):?字節(jié)=32?時(shí)間=16ms?TTL=54
來自?183.232.231.174?的回復(fù):?字節(jié)=32?時(shí)間=16ms?TTL=54
來自?183.232.231.174?的回復(fù):?字節(jié)=32?時(shí)間=16ms?TTL=54
183.232.231.172?的?Ping?統(tǒng)計(jì)信息:
????數(shù)據(jù)包:?已發(fā)送?=?3,已接收?=?3,丟失?=?0?(0%?丟失),
往返行程的估計(jì)時(shí)間(以毫秒為單位):
????最短?=?16ms,最長?=?16ms,平均?=?16ms
以上輸出顯示www.baidu.com
的ip地址:183.232.231.174
,然后使用Wireshark
的過濾器僅顯示與www.baidu.com
通信的tcp
數(shù)據(jù)包:
ip.src_host?==?"183.232.231.174"?or?ip.dst_host?==?"183.232.231.174"?and?tcp
使用Wireshark
抓包分析后,驗(yàn)證TCP正常連接三次握手與上節(jié)描述的一致。
為什么是三次握手?
為什么是三次握手?三次握手主要有兩個(gè)目的:信息對等和防止超時(shí)。
信息對等
兩臺機(jī)器通信時(shí)都需要確認(rèn)四個(gè)信息:
自己發(fā)報(bào)文的能力
自己收報(bào)文的能力
對方發(fā)報(bào)文的能力
對方收報(bào)文的通知
第一次握手
第一次握手A機(jī)器向B機(jī)器發(fā)送SYN
數(shù)據(jù)包,此時(shí)只有B機(jī)器能確認(rèn)自己收報(bào)文的能力和對方發(fā)報(bào)文的能力。
一次握手完成B機(jī)器能夠確認(rèn)的信息有:
√B機(jī)器收報(bào)文的能力
√A機(jī)器發(fā)報(bào)文的能力
第二次握手
每二次握手后B響應(yīng)A機(jī)器的SYN
數(shù)據(jù)包,此時(shí)A機(jī)器就能確認(rèn):自己發(fā)報(bào)文的能力、自己收報(bào)文的能力、對方發(fā)報(bào)文的能力、對方收報(bào)文的能力
二次握手完成A機(jī)器能夠確認(rèn)的信息有:
√A機(jī)器發(fā)報(bào)文的能力
√A機(jī)器收報(bào)文的能力
√B機(jī)器發(fā)報(bào)文的能力
√B機(jī)器收報(bào)文的能力
第三次握手
每三次握手后A應(yīng)答B(yǎng)機(jī)器的SYN + ACK
數(shù)據(jù)包,此時(shí)B機(jī)器就能確認(rèn):自己發(fā)報(bào)文的能力、對方收報(bào)文的能力
三次握手完成B機(jī)器能夠確認(rèn)的信息有:
√B機(jī)器發(fā)報(bào)文的能力
√A機(jī)器收報(bào)文的能力
至此經(jīng)過三次握手A、B機(jī)器就能做到信息對等,雙方都能確認(rèn)自己和對方的收、發(fā)報(bào)文的能力,最后方便理解將信息對等制作成一個(gè)小表格:
防止超時(shí)
三次握手除了保證信息對等也是了防止請求超時(shí)導(dǎo)致臟連接。TTL網(wǎng)絡(luò)報(bào)文的生存往往會(huì)超過TCP請求超時(shí)時(shí)間,如果兩次握手就能創(chuàng)建連接,傳輸數(shù)據(jù)并釋放連接后,第一個(gè)超時(shí)的連接請求才到達(dá)B機(jī)器,B機(jī)器 會(huì)以為是 A 創(chuàng)建新連接的請求,然后確認(rèn)同意創(chuàng)建連接。因?yàn)锳機(jī)器的狀態(tài)不是SYN_SENT
,所以會(huì)直接丟棄了B的確認(rèn)數(shù)據(jù),導(dǎo)致 B 機(jī)器單方面的創(chuàng)建連接完畢。
如果是三次握手,則 B 機(jī)器收到連接請求后,同樣會(huì)向 A 機(jī)器確同意創(chuàng)建連接,但因?yàn)?A 不是SYN_SENT
狀態(tài),所以 A機(jī)器 不會(huì)回復(fù) B 機(jī)器確認(rèn)創(chuàng)建連接請求,而 B 機(jī)器到一段時(shí)間后由于長時(shí)間沒有收到確認(rèn)信息,最終會(huì)導(dǎo)致連接創(chuàng)建失敗,因此不會(huì)出現(xiàn)臟連接。
TCP斷開連接
TCP是全雙工通信,雙方都能作為數(shù)據(jù)的發(fā)送方和接收方,但TCP會(huì)有斷開的時(shí)候。TCP建立連接需要三次握手而斷開連接卻要四次,如圖所示為TCP斷開連接四次揮手過程:
A 機(jī)器發(fā)送關(guān)閉數(shù)據(jù)包將
FIN
設(shè)置為1,假設(shè)序列號為u
,發(fā)完關(guān)閉數(shù)據(jù)包后此時(shí) A 機(jī)器處理FIN_WAIT_1
狀態(tài)B 收到關(guān)閉連接請求后,通知應(yīng)用程序處理完剩下的數(shù)據(jù)
B 響應(yīng) A 的關(guān)閉連接請求,將
ACK
標(biāo)志設(shè)置為1,seq為v
,ack為u+1
,隨后 B 機(jī)器處于CLOSE_WAIT
狀態(tài)A 收到應(yīng)答后,處于
FIN_WAIT_2
狀態(tài),繼續(xù)等待 B 機(jī)器的FIN
數(shù)據(jù)包B 處理好現(xiàn)場后,主動(dòng)向 A 機(jī)器發(fā)送數(shù)據(jù)包,并將
FIN
和ACK
標(biāo)志設(shè)置為1,seq為w
,ack為u+1
,隨后處于LAST_WAIT
狀態(tài)等待 A 機(jī)器的應(yīng)答A 機(jī)器收到
FIN
數(shù)據(jù)包后,隨后發(fā)送ACK
數(shù)據(jù)包,seq為u+1
,ack為w+1
, 此時(shí) A 機(jī)器處理TIME_WAIT
狀態(tài)B 機(jī)器收到
ACK
響應(yīng)包后,進(jìn)行CLOSED
狀態(tài),連接正常關(guān)閉A 機(jī)器在
TIME_WAIT
狀態(tài)等待2MSL
后,也進(jìn)入CLOSEED
狀態(tài),連接關(guān)閉
什么是2MSL:MSL是Maximum Segment Lifetime英文的縮寫,中文可以譯為“報(bào)文最大生存時(shí)間”,
2MSL即兩倍的MSL
四次揮手?jǐn)嚅_連接可以用更形象的方式來表達(dá):
男生 :我們分手吧。
女生 :好的,我需要去家里把東西收拾完,再發(fā)消息給你。(此時(shí)男生不能再擁抱女生)
。。。,一個(gè)小時(shí)后
女生 :我收拾完了,分手吧(此時(shí)女生也不能再擁抱男生)
男生:好的(此時(shí)雙方約定一段時(shí)間后,才可以分別找新的對象)
TCP四次揮手抓包驗(yàn)證
抓包過程與與三次握手抓包過程一致,這里不描述。直接看訪問后抓包的截圖:
第一個(gè)包是由
192.168.1.6
這臺機(jī)器(也就是客戶機(jī)),發(fā)送了一個(gè)FIN
包,seq為80
,ack為2782
第二個(gè)包由
183.232.231.174
(服務(wù)器),對192.168.1.6
這臺機(jī)器(也就是客戶機(jī))發(fā)送了一個(gè)ACK
包,seq為2782
,ack為81
第三個(gè)包由
183.232.231.174
(服務(wù)器),對192.168.1.6
這臺機(jī)器(也就是客戶機(jī))發(fā)送了一個(gè)ACK
和FIN
包,seq為2782
,ack為81
第四個(gè)包由
192.168.1.6
,向服務(wù)器響應(yīng)了一個(gè)ACK
包,seq為81
,ack為2783
四次揮手流程與我們描述的一致。
TIME_WAIT 狀態(tài)
主動(dòng)要求關(guān)閉的機(jī)器(機(jī)器A)表示收到對方的FIN
報(bào)文后,并發(fā)送出ACK
報(bào)文后,進(jìn)行TIME_WAIT
狀態(tài),等待2MSL
后進(jìn)行CLOSED
狀態(tài)。如果在TIME_WAIT_1
時(shí)收到FIN
標(biāo)志和ACK
標(biāo)志報(bào)文時(shí),可以直接進(jìn)入TIME_WAIT
狀態(tài),而無需進(jìn)入TIME_WAIT_2
狀態(tài)。
為什么要有 TIME_WAIT
確認(rèn)被動(dòng)關(guān)閉(機(jī)器B)能夠順利進(jìn)入CLOSED
狀態(tài)
假如A機(jī)器發(fā)送最后一個(gè)ACK
后,但由于網(wǎng)絡(luò)原因ACK
包未能到達(dá) B 機(jī)器,此時(shí) B機(jī)器通常會(huì)認(rèn)為 A機(jī)器 沒有收到 FIN+ACK
報(bào)文,會(huì)重發(fā)一次FIN+ACK
報(bào)文。如果 A機(jī)器 發(fā)送最后一個(gè)ACK
后,自私的關(guān)閉連接進(jìn)入 CLOSED
狀態(tài),就可能導(dǎo)致 B 無法收到ACK
報(bào)文,無法正常關(guān)閉。
防止失效請求
TIME_WAIT 狀態(tài)可以防止已失效的請求包與正常連接的請求數(shù)據(jù)包混淆而發(fā)生異常。因?yàn)門IME_WAIT 狀態(tài)無法真正釋放句柄資源,在此期間, Socket中使用的本地端口在默認(rèn)情況下不能再被使用。
CLOSE_WAIT 狀態(tài)
被動(dòng)關(guān)閉的機(jī)器(機(jī)器B)在收到對方發(fā)送的,FIN
報(bào)文后,馬上回復(fù)ACK
報(bào)文,進(jìn)入CLOSE_WAIT
狀態(tài)。通知應(yīng)用程序,處理剩下的數(shù)據(jù),釋放資源。
特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:
長按訂閱更多精彩▼
如有收獲,點(diǎn)個(gè)在看,誠摯感謝
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!