1 TCP三次握手四次揮手
TCP
在傳輸之前會進(jìn)行三次溝通,一般稱為三次握手
,傳完數(shù)據(jù)斷開的時(shí)候要進(jìn)行四次揮手
1.1 數(shù)據(jù)包說明
1.1.1 TCP數(shù)據(jù)包
數(shù)據(jù)包說明:
-
源端口號
(16 位):它(連同源主機(jī) IP 地址)標(biāo)識源主機(jī)的一個(gè)應(yīng)用進(jìn)程 -
目的端口號
(16 位):它(連同目的主機(jī) IP 地址)標(biāo)識目的主機(jī)的一個(gè)應(yīng)用進(jìn)程。這兩個(gè)值加上 IP 報(bào)頭中的源主機(jī) IP 地址和目的主機(jī) IP 地址確定唯一一個(gè) TCP 連接 -
順序號seq
(32 位): 用來標(biāo)識從TCP
源端向TCP
目的端發(fā)送的數(shù)據(jù)字節(jié)流,它表示在這個(gè)報(bào)文段中的第一個(gè)數(shù)據(jù)字節(jié)的順序號。如果將字節(jié)流看作在兩個(gè)應(yīng)用程序間的單向流動,則TCP
用順序號對每個(gè)字節(jié)進(jìn)行計(jì)數(shù)。序號是32bit
的無符號數(shù), 序號到達(dá)2^32-1
后又從 0 開始。 當(dāng)建立一個(gè)新的連接時(shí),SYN
標(biāo)志變1
,順序號字段包含 由這個(gè)主機(jī)選擇的 該連接的初始順序號ISN (Initial Sequence Number )
-
確認(rèn)號 ack
(32 位): 包含發(fā)送確認(rèn)的一端所期望收到的下一個(gè)順序號。因此,確認(rèn)序號應(yīng)當(dāng)是上次已成功收到數(shù)據(jù)字節(jié)順序號加 1
。 只有ACK
標(biāo)志為 1 時(shí)確認(rèn)序號字段才有效。TCP
為應(yīng)用層提供全雙工服務(wù),這意味數(shù)據(jù)能在兩個(gè)方向上獨(dú)立地進(jìn)行傳輸。因此,連接的每一端必須保持每個(gè)方向上的傳輸數(shù)據(jù)順序號。 -
TCP
報(bào)頭長度(4 位):給出報(bào)頭中32bit
字的數(shù)目, 它實(shí)際上指明數(shù)據(jù)從哪里開始。 需要這個(gè)值是因?yàn)槿芜x字段的長度是可變的。這個(gè)字段占4bit
,因此TCP
最多有 60 字節(jié)的首部。然而,沒有任選字段,正常的長度是20字節(jié)
-
保留位
(6 位):保留給將來使用,目前必須置為 0 。 -
控制位
(control flags
, 6 位):在TCP
報(bào)頭中有 6 個(gè)標(biāo)志比特,它們中的多個(gè)可同時(shí)被設(shè)置為 1 。依次為:URG
:為 1 表示緊急指針有效,為 0 則忽略緊急指針值。ACK
:為 1 表示確認(rèn)號有效,為 0 表示報(bào)文中不包含確認(rèn)信息,忽略確認(rèn)號字段。PSH
:為 1 表示是帶有PUSH
標(biāo)志的數(shù)據(jù), 指示接收方應(yīng)該盡快將這個(gè)報(bào)文段交給應(yīng)用層而不用等待緩沖區(qū)裝滿。RST
: 用于復(fù)位由于主機(jī)崩潰或其他原因而出現(xiàn)錯誤的連接。它還可以用于拒絕非法的報(bào)文段和拒絕連接請求。一般情況下,如果收到一個(gè)RST
為 1 的報(bào)文,那么一定發(fā)生了某些問題。SYN
:同步序號, 為 1 表示連接請求,用于建立連接和使順序號同步synchronize
FIN
: 用于釋放連接,為 1 表示發(fā)送方已經(jīng)沒有數(shù)據(jù)發(fā)送了,即關(guān)閉本方數(shù)據(jù)流。 -
窗口大小
(16 位):數(shù)據(jù)字節(jié)數(shù),表示從確認(rèn)號開始,本報(bào)文的源方可以接收的字節(jié)數(shù),即源方接收窗口大小。窗口大小是一個(gè)16bit
字段,因而窗口大小最大為65535
字節(jié)。 -
校驗(yàn)和
(16 位):此校驗(yàn)和是對整個(gè)的TCP
報(bào)文段, 包括TCP
頭部和TCP
數(shù)據(jù),以 16 位字進(jìn)行計(jì)算所得。這是一個(gè)強(qiáng)制性的字段,一定是由發(fā)送端計(jì)算和存儲, 并由接收端進(jìn)行驗(yàn)證。 -
緊急指針
(16 位):只有當(dāng)URG
標(biāo)志置 1 時(shí)緊急指針才有效。TCP
的緊急方式是發(fā)送端向另一端發(fā)送緊急數(shù)據(jù)的一種方式 -
選項(xiàng)
:最常見的可選字段是最長報(bào)文大小,又稱為MSS(Maximum Segment Size)
。每個(gè)連接方通常都在通信的第一個(gè)報(bào)文段(為建立連接而設(shè)置 SYN 標(biāo)志的那個(gè)段)中指明這個(gè)選項(xiàng),它指明本端所能接收的最大長度的報(bào)文段。選項(xiàng)長度不一定是 32 位字的整數(shù)倍,所以要加填充位,使得報(bào)頭長度成為整字?jǐn)?shù)。 -
數(shù)據(jù)
:TCP
報(bào)文段中的數(shù)據(jù)部分是可選的。在一個(gè)連接建立和一個(gè)連接終止時(shí),雙方交換的報(bào)文段僅有 TCP 首部。如果一方?jīng)]有數(shù)據(jù)要發(fā)送,也使用沒有任何數(shù)據(jù)的首部來確認(rèn)收到的數(shù)據(jù)。在處理超時(shí)的許多情況中,也會發(fā)送不帶任何數(shù)據(jù)的報(bào)文段
1.1.2 UDP數(shù)據(jù)包
-
源端口號
(Source Port
):這個(gè)字段占據(jù)UDP
報(bào)文頭的前 16 位,通常包含發(fā)送數(shù)據(jù)報(bào)的應(yīng)用程序所使用的UDP
端口。接收端的應(yīng)用程序利用這個(gè)字段的值作為發(fā)送響應(yīng)的目的地址。這個(gè)字段是可選項(xiàng),有時(shí)不會設(shè)置源端口號。沒有源端口號就默認(rèn)為 0 ,通常用于不需要返回消息的通信中。 -
目標(biāo)端口號
(Destination Port
): 表示接收端端口,字段長為 16 位。 -
長度
(Length
): 該字段占據(jù) 16 位,表示 UDP 數(shù)據(jù)報(bào)長度,包含 UDP 報(bào)文頭和 UDP 數(shù)據(jù)長度。因?yàn)?UDP 報(bào)文頭長度是 8 個(gè)字節(jié),所以這個(gè)值最小為 8,最大長度為2 ^ 16 = 65535
字節(jié)(即報(bào)文長度為64K) -
校驗(yàn)和
(Checksum
):UDP
使用校驗(yàn)和來保證數(shù)據(jù)安全性,UDP
的校驗(yàn)和也提供了差錯檢測
功能,差錯檢測
用于校驗(yàn)報(bào)文段從源到目標(biāo)主機(jī)的過程中,數(shù)據(jù)的完整性是否發(fā)生了改變
轉(zhuǎn)載于:https://mp.weixin.qq.com/s/aAAZQh8r7eCsIR9GsSvauw
1.1.3 TCP和UDP差異
- UDP 沒有所謂的序列號和確認(rèn)號,所以不會對數(shù)據(jù)進(jìn)行確認(rèn),數(shù)據(jù)丟失后也不會進(jìn)行重傳,所以 UDP 是一種不可靠的協(xié)議
- TCP具有高可靠性,確保傳輸數(shù)據(jù)的正確性,不出現(xiàn)丟失或亂序,傳輸數(shù)據(jù)量大,沒有限制
- TCP相對于UDP速度慢一點(diǎn),效率低,而且要求系統(tǒng)資源較多,每個(gè)連接都會占用系統(tǒng)的CPU、內(nèi)存等硬件資源
- UDP速度快、操作簡單、要求系統(tǒng)資源較少,傳輸數(shù)據(jù)少,理論64K
- UDP不可靠,可能會出現(xiàn)丟包、亂序、數(shù)據(jù)不完整
1.1.4 TCP可靠性傳輸機(jī)制
為了保持 TCP
的可靠性傳輸,TCP
協(xié)議采用了以下機(jī)制:
-
序號與確認(rèn)機(jī)制
:TCP
使用序號 (sequence number)
來對數(shù)據(jù)進(jìn)行編號,并使用確認(rèn)(acknowledgment
)來確認(rèn)接收到的數(shù)據(jù)。發(fā)送方將每個(gè)數(shù)據(jù)段分配一個(gè)序號,接收方通過發(fā)送確認(rèn)消息來告知發(fā)送方已成功接收到數(shù)據(jù)。如果發(fā)送方在一定時(shí)間內(nèi)沒有收到確認(rèn)消息,就會重新發(fā)送數(shù)據(jù)。 -
數(shù)據(jù)段校驗(yàn)和
:TCP
使用校驗(yàn)和(checksum)
來檢測數(shù)據(jù)在傳輸過程中是否發(fā)生了錯誤。發(fā)送方在發(fā)送數(shù)據(jù)前計(jì)算校驗(yàn)和,并將其附加到數(shù)據(jù)段中。接收方在接收到數(shù)據(jù)后也會計(jì)算校驗(yàn)和,并與發(fā)送方發(fā)送的校驗(yàn)和進(jìn)行比對。如果校驗(yàn)和不匹配,則表明數(shù)據(jù)在傳輸過程中發(fā)生了錯誤,接收方會要求發(fā)送方重新發(fā)送數(shù)據(jù)。 -
確認(rèn)重傳機(jī)制
:如果發(fā)送方在一定時(shí)間內(nèi)沒有收到確認(rèn)消息,就會認(rèn)為數(shù)據(jù)丟失,并重新發(fā)送數(shù)據(jù)。接收方在收到重復(fù)的數(shù)據(jù)時(shí)會丟棄重復(fù)的數(shù)據(jù),只發(fā)送一個(gè)確認(rèn)消息,以避免重復(fù)處理。 -
滑動窗口機(jī)制
:TCP
使用滑動窗口(sliding window)機(jī)制來控制發(fā)送方和接收方之間的數(shù)據(jù)流量。發(fā)送方將數(shù)據(jù)分成多個(gè)數(shù)據(jù)段,并將其發(fā)送給接收方。接收方使用滑動窗口來控制可以接收的數(shù)據(jù)量。滑動窗口的大小可以根據(jù)網(wǎng)絡(luò)狀況動態(tài)調(diào)整,以確保數(shù)據(jù)的可靠傳輸。 -
流量控制
:TCP
使用流量控制機(jī)制來避免發(fā)送方發(fā)送過多的數(shù)據(jù),導(dǎo)致接收方無法處理。接收方可以通過發(fā)送窗口大小告訴發(fā)送方可以接收的數(shù)據(jù)量。發(fā)送方需要根據(jù)接收方的窗口大小來控制發(fā)送的數(shù)據(jù)量,以避免數(shù)據(jù)的擁塞和丟失。 -
擁塞控制
:TCP
使用擁塞控制機(jī)制來避免網(wǎng)絡(luò)擁塞。發(fā)送方根據(jù)網(wǎng)絡(luò)狀況動態(tài)調(diào)整發(fā)送速率,以避免發(fā)送過多的數(shù)據(jù)導(dǎo)致網(wǎng)絡(luò)擁塞。TCP
使用擁塞窗口 (congestion window)
來控制發(fā)送方的發(fā)送速率。擁塞窗口的大小可以根據(jù)網(wǎng)絡(luò)狀況動態(tài)調(diào)整,以確保網(wǎng)絡(luò)的穩(wěn)定性和可靠性。 -
最大消息長度
:為了防止因數(shù)據(jù)包過大而導(dǎo)致傳輸錯誤,TCP
設(shè)定了最大消息長度的限制
1.2 三次握手
1.2.1 三次握手定義
客戶端向服務(wù)器發(fā)送建立連接請求
一開始,客戶端和服務(wù)端都處于 CLOSE
狀態(tài)。先是服務(wù)端主動監(jiān)聽某個(gè)端口,處于 LISTEN
狀態(tài)
-
第一次握手:主機(jī) A 發(fā)送位碼為
syn=1
,隨機(jī)產(chǎn)生seq number=1234567
的數(shù)據(jù)包到服務(wù)器,主機(jī) B 由SYN=1
知道, A 要求建立聯(lián)機(jī);該報(bào)文不包含應(yīng)用層數(shù)據(jù),之后客戶端處于SYN-SENT
狀態(tài)。 -
第二次握手:主 機(jī) B 收 到 請 求 后 要 確 認(rèn) 聯(lián) 機(jī) 信 息 , 向 A 發(fā) 送
ack number=( 主 機(jī) A 的seq+1),SYN=1,ACK=1
,隨機(jī)產(chǎn)生seq=7654321
的包,把TCP
首部的確認(rèn)應(yīng)答號
,把SYN
和ACK
標(biāo)志位置為 1,最后把該報(bào)文發(fā)給客戶端,該報(bào)文也不包含應(yīng)用層數(shù)據(jù),之后服務(wù)端處于SYN-RCVD
狀態(tài)。 -
第三次握手: 主機(jī) A 收到后檢查
ack number
是否正確,即第一次發(fā)送的seq number+1
,以及位碼ACK
是否為 1,若正確, 主機(jī) A 會再發(fā)送ack number=(主機(jī) B 的 seq+1),ACK=1
,主機(jī) B 收到后確認(rèn)seq 值
與ACK=1
則連接建立成功。最后把報(bào)文發(fā)送給服務(wù)端,這次報(bào)文可以攜帶客戶到服務(wù)端的數(shù)據(jù)
,之后客戶端處于ESTABLISHED
狀態(tài)。
最后,服務(wù)端收到客戶端的應(yīng)答報(bào)文后,也進(jìn)入ESTABLISHED
狀態(tài)
1.2.2 三次握手問題
1.2.2.1 問題引入分析
概括起來,是這兩個(gè)問題:
-
問
:TCP
三次握手中,客戶端收到的第二次握手中ack
確認(rèn)號不是自己期望的,會發(fā)生什么?是直接丟棄 or 回RST
報(bào)文?答
:回RST
報(bào)文 -
問
:什么情況下會收到不正確的 ack(第二次握手中的 ack) 呢答
:當(dāng)客戶端發(fā)起多次SYN
報(bào)文,然后網(wǎng)絡(luò)擁堵的情況下,舊的 SYN 報(bào)文
比新的 SYN 報(bào)文
早抵達(dá)服務(wù)端,此時(shí)服務(wù)端就會按照收到的舊的 SYN 報(bào)文
回復(fù)syn+ack
報(bào)文,而此報(bào)文的確認(rèn)號并不是客戶端期望收到的,于是客戶端就會回RST
報(bào)文
假如 TCP
三次握手中,客戶端收到的第二次握手中 ack
確認(rèn)號不是自己期望的過程如下:
當(dāng)客戶端連續(xù)發(fā)送多次建立連接的 SYN
報(bào)文,然后在網(wǎng)絡(luò)擁堵的情況,就會發(fā)生客戶端收到不正確的 ack
的情況。具體過程如下:
- 客戶端先發(fā)送了
SYN(seq = 90)
報(bào)文,但是被網(wǎng)絡(luò)阻塞了,服務(wù)端并沒有收到,接著客戶端又重新發(fā)送了SYN(seq = 100)
報(bào)文,注意不是重傳SYN
,重傳的SYN
的序列號是一樣的。 -
舊 SYN 報(bào)文
比最新的 SYN
報(bào)文早到達(dá)了服務(wù)端,那么此時(shí)服務(wù)端就會回一個(gè)SYN + ACK
報(bào)文給客戶端,此報(bào)文的確認(rèn)號是 91(90+1)。 - 客戶端收到后,發(fā)行自己期望收到的確認(rèn)號應(yīng)該是 100+1,而不是 90 + 1,于是就會回
RST
報(bào)文。 - 服務(wù)端收到 RST 報(bào)文后,就會中止連接。
- 后續(xù)最新的 SYN 抵達(dá)了服務(wù)端后,客戶端與服務(wù)端就可以正常的完成三次握手了。
上述中的舊 SYN 報(bào)文
稱為歷史連接
,TCP
使用三次握手建立連接的最主要原因就是防止歷史連接
初始化了連接。
1.2.2.2 歷史連接
如果是兩次握手連接,就無法阻止歷史連接
,那為什么TCP
兩次握手為什么無法阻止歷史連接呢?
先說結(jié)論,主要是因?yàn)樵趦纱挝帐值那闆r下,被動發(fā)起方
沒有中間狀態(tài)給主動發(fā)起方
來阻止歷史連接,導(dǎo)致被動發(fā)起方
可能建立一個(gè)歷史連接,造成資源浪費(fèi)。
假如在兩次握手的情況下,被動發(fā)起方
在收到 SYN
報(bào)文后,就進(jìn)入 ESTABLISHED
狀態(tài),意味著這時(shí)可以給對方發(fā)送數(shù)據(jù)給,但是主動發(fā)
起方此時(shí)還沒有進(jìn)入 ESTABLISHED
狀態(tài),假設(shè)這次是歷史連接,主動發(fā)起方判斷到此次連接為歷史連接,那么就會回 RST
報(bào)文來斷開連接,而被動發(fā)起方
在第一次握手的時(shí)候就進(jìn)入 ESTABLISHED
狀態(tài),所以它可以發(fā)送數(shù)據(jù)的,但是它并不知道這個(gè)是歷史連接,它只有在收到 RST
報(bào)文后,才會斷開連接。
可以看到,上面這種場景下,被動發(fā)起方
在向主動發(fā)起方
發(fā)送數(shù)據(jù)前,并沒有阻止掉歷史連接,導(dǎo)致被動發(fā)起方
建立了一個(gè)歷史連接,又白白發(fā)送了數(shù)據(jù),妥妥地浪費(fèi)了被動發(fā)起方
的資源。
因此,要解決這種現(xiàn)象,最好就是在被動發(fā)起方
發(fā)送數(shù)據(jù)前,也就是建立連接之前,要阻止掉歷史連接,這樣就不會造成資源浪費(fèi),而要實(shí)現(xiàn)這個(gè)功能,就需要三次握手。
1.2.2.3 同步雙方初始序列號
TCP
協(xié)議的通信雙方, 都必須維護(hù)一個(gè)序列號
, 序列號
是可靠傳輸?shù)囊粋€(gè)關(guān)鍵因素,它的作用:
- 接收方可以去除重復(fù)的數(shù)據(jù);
- 接收方可以根據(jù)數(shù)據(jù)包的序列號按序接收;
- 可以標(biāo)識發(fā)送出去的數(shù)據(jù)包中, 哪些是已經(jīng)被對方收到的(通過
ACK
報(bào)文中的序列號知道);
可見,序列號在 TCP
連接中占據(jù)著非常重要的作用,所以當(dāng)客戶端發(fā)送攜帶初始序列號
的 SYN
報(bào)文的時(shí)候,需要服務(wù)端回一個(gè) ACK
應(yīng)答報(bào)文,表示客戶端的 SYN
報(bào)文已被服務(wù)端成功接收,那當(dāng)服務(wù)端發(fā)送初始序列號
給客戶端的時(shí)候,依然也要得到客戶端的應(yīng)答回應(yīng),這樣一來一回,才能確保雙方的初始序列號能被可靠的同步
。
四次握手其實(shí)也能夠可靠的同步雙方的初始化序號,但由于第二步和第三步可以優(yōu)化成一步,所以就成了 三次握手
而兩次握手只保證了一方的初始序列號能被對方成功接收,沒辦法保證雙方的初始序列號都能被確認(rèn)接收。
1.2.2.4 避免資源浪費(fèi)
如果只有兩次握手
,當(dāng)客戶端發(fā)生的 SYN
報(bào)文在網(wǎng)絡(luò)中阻塞,客戶端沒有接收到 ACK
報(bào)文,就會重新發(fā)送 SYN
,由于沒有第三次握手,服務(wù)端不清楚客戶端是否收到了自己回復(fù)的 ACK
報(bào)文,所以服務(wù)端每收到一個(gè) SYN
就只能先主動建立一個(gè)連接,這會造成什么情況呢?
如果客戶端發(fā)送的
SYN
報(bào)文在網(wǎng)絡(luò)中阻塞了,重復(fù)發(fā)送多次SYN
報(bào)文,那么服務(wù)端在收到請求后就會建立多個(gè)冗余的無效鏈接,造成不必要的資源浪費(fèi)。
兩次握手會造成資源浪費(fèi)
即兩次握手會造成消息滯留情況下,服務(wù)端重復(fù)接受無用的連接請求 SYN 報(bào)文,而造成重復(fù)分配資源。
1.3 四次揮手
TCP
建立連接要進(jìn)行三次握手,而斷開連接要進(jìn)行四次。這是由于 TCP
的半關(guān)閉造成的。因?yàn)?TCP
連接是全雙工的(即數(shù)據(jù)可在兩個(gè)方向上同時(shí)傳遞)所以進(jìn)行關(guān)閉時(shí)每個(gè)方向上都要單獨(dú)進(jìn)行關(guān)閉。這個(gè)單方向的關(guān)閉就叫半關(guān)閉
。當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù),就發(fā)送一個(gè) FIN
來向另一方通告將要終止這個(gè)方向的連接
首先進(jìn)行關(guān)閉的一方將執(zhí)行主動關(guān)閉,而另一方執(zhí)行被動關(guān)閉
- 關(guān)閉客戶端到服務(wù)器的連接:首先客戶端 A 發(fā)送一個(gè)
FIN
,用來關(guān)閉客戶到服務(wù)器的數(shù)據(jù)傳送,然后等待服務(wù)器的確認(rèn)。其中終止標(biāo)志位FIN=1
,序列號seq=u
- 服務(wù)器收到這個(gè)
FIN
,它發(fā)回一個(gè)ACK
,確認(rèn)號ack
為收到的序號加 1 - 關(guān)閉服務(wù)器到客戶端的連接:也是發(fā)送一個(gè)
FIN
給客戶端。 - 客戶段收到
FIN
后,并發(fā)回一個(gè)ACK
報(bào)文確認(rèn),并將確認(rèn)序號 seq
設(shè)置為收到序號加 1
主機(jī) A 發(fā)送 FIN 后,進(jìn)入終止等待狀態(tài), 服務(wù)器 B 收到主機(jī) A 連接釋放報(bào)文段后,就立即給主機(jī) A 發(fā)送確認(rèn),然后服務(wù)器 B 就進(jìn)入 close-wait
狀態(tài),此時(shí) TCP
服務(wù)器進(jìn)程就通知高層應(yīng)用進(jìn)程,因而從 A 到 B 的連接就釋放了。此時(shí)是半關(guān)閉
狀態(tài)。即 A 不可以發(fā)送給B,但是 B 可以發(fā)送給 A。此時(shí),若 B 沒有數(shù)據(jù)報(bào)要發(fā)送給 A 了,其應(yīng)用進(jìn)程就通知 TCP
釋放連接,然后發(fā)送給 A 連接釋放報(bào)文段,并等待確認(rèn)。 A 發(fā)送確認(rèn)后,進(jìn)入 time-wait
文章來源:http://www.zghlxwxcb.cn/news/detail-799932.html
注意
,此時(shí) TCP
連接還沒有釋放掉,然后經(jīng)過時(shí)間等待計(jì)時(shí)器設(shè)置的 2MSL
后, A 才進(jìn)入到close狀態(tài)
在四次揮手期間,服務(wù)端不接收報(bào)文而發(fā)送RST
報(bào)文給客戶端,客戶端收到RST
報(bào)文會報(bào)錯(NoHttpResponseException
)文章來源地址http://www.zghlxwxcb.cn/news/detail-799932.html
到了這里,關(guān)于TCP之三次握手四次揮手與UDP區(qū)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!