常規(guī)回答:“因?yàn)槿挝帐植拍鼙WC雙方具有接收和發(fā)送的能力”
原因一:避免歷史連接
三次握手的首要原因是為了防止舊的重復(fù)連接初始化造成混亂。
假設(shè):客戶端先發(fā)送了SYN(seq=90)報文,然后客戶端宕機(jī)了,而且這個SYN報文還被網(wǎng)絡(luò)阻塞了,服務(wù)端并沒有收到,接著客戶端重啟后,又重新向服務(wù)端建立連接,發(fā)送了SYN(seq=100)報文。(這里不是重傳,而是重新發(fā)送請求)
?客戶端連續(xù)發(fā)送多次SYN(都是同一個四元組)建立連接的報文,在網(wǎng)絡(luò)擁堵的情況下:
- 一個[舊的SYN報文]比[最新的SYN]報文早到達(dá)了服務(wù)端,那么此時服務(wù)端就回一個SYN+ACK報文給客戶端,此報文中的確認(rèn)號是91(90+1)
- 客戶端收到后,發(fā)現(xiàn)自己期望收到的確認(rèn)號應(yīng)該是100+1,而不是90+1,于是就會回RST報文
- 服務(wù)端收到RST報文后,就會釋放連接。
- 后續(xù)最新的SYN抵達(dá)了服務(wù)端,客戶端與服務(wù)端就可以正常的完成三次握手了。
上述中的「舊 SYN 報文」稱為歷史連接,TCP 使用三次握手建立連接的最主要原因就是防止「歷史連接」初始化了連接。
?TIP
如果服務(wù)端在收到 RST 報文之前,先收到了「新 SYN 報文」,也就是服務(wù)端收到客戶端報文的順序是:「舊 SYN 報文」->「新 SYN 報文」,此時會發(fā)生什么?
當(dāng)服務(wù)端第一次收到 SYN 報文,也就是收到 「舊 SYN 報文」時,就會回復(fù)?
SYN + ACK
?報文給客戶端,此報文中的確認(rèn)號是 91(90+1)。然后這時再收到「新 SYN 報文」時,就會回?Challenge Ack?(opens new window)報文給客戶端,這個 ack 報文并不是確認(rèn)收到「新 SYN 報文」的,而是上一次的 ack 確認(rèn)號,也就是91(90+1)。所以客戶端收到此 ACK 報文時,發(fā)現(xiàn)自己期望收到的確認(rèn)號應(yīng)該是 101,而不是 91,于是就會回 RST 報文。
如果是兩次握手連接,就無法阻止歷史連接,那為什么TCP兩次握手就無法阻止歷史連接呢?
因?yàn)樵趦纱挝帐值那闆r下,服務(wù)端沒有中間狀態(tài)給客戶端來阻止歷史連接,導(dǎo)致服務(wù)端可能建立一個歷史連接,造成資源浪費(fèi)。
在兩次握手的情況下,服務(wù)端在收到 SYN 報文后,就進(jìn)入 ESTABLISHED 狀態(tài),意味著這時可以給對方發(fā)送數(shù)據(jù),但是客戶端此時還沒有進(jìn)入 ESTABLISHED 狀態(tài),假設(shè)這次是歷史連接,客戶端判斷到此次連接為歷史連接,那么就會回 RST 報文來斷開連接,而兩次握手而服務(wù)端在第一次握手的時候就進(jìn)入 ESTABLISHED 狀態(tài),所以它可以發(fā)送數(shù)據(jù)的,但是它并不知道這個是歷史連接,它只有在收到 RST 報文后,才會斷開連接。
?可以看到,如果采用兩次握手建立 TCP 連接的場景下,服務(wù)端在向客戶端發(fā)送數(shù)據(jù)前,并沒有阻止掉歷史連接,導(dǎo)致服務(wù)端建立了一個歷史連接,又白白發(fā)送了數(shù)據(jù),妥妥地浪費(fèi)了服務(wù)端的資源。
因此,要解決這種現(xiàn)象,最好就是在服務(wù)端發(fā)送數(shù)據(jù)前,也就是在建立連接前,要阻止掉歷史連接,這樣就不會造成資源浪費(fèi),所以需要三次握手。
所以TCP使用三次握手建立連接的最主要原因是防止[歷史連接]初始化了連接
原因二:同步雙方初始序列號
TCP協(xié)議的通信雙方,都必須維護(hù)一個[序列號],序列號是可靠傳輸?shù)囊粋€關(guān)鍵因素,它的作用:
- 接收方可以去除重復(fù)數(shù)據(jù)
- 接收方可以根據(jù)數(shù)據(jù)包的序列號按序接收
- 可以標(biāo)識發(fā)送出去的數(shù)據(jù)包中,哪些是已經(jīng)被對方收到的(通過ACK報文中的序列號知道)
可見,序列號在TCP連接中占據(jù)著非常重要的作用,所以當(dāng)客戶端發(fā)送攜帶[初始序列號]的SYN報文的時候,需要服務(wù)端回一個ACK應(yīng)答報文,表示客戶端的SYN報文已被服務(wù)端成功接收,那么當(dāng)服務(wù)端發(fā)送[初始序列號]給客戶端的時候,依然也要得到客戶端的應(yīng)答,這樣一來一回,才能確保雙方的初始序列號能被可靠的同步。
四次握手其實(shí)也能夠可靠的同步雙方的初始化序號,但由于第二步和第三步可以優(yōu)化成一步,所以就成了[三次握手]。
?兩次握手只保證了一方的初始序列號能被對方成功接收,沒辦法保證雙方的初始序列號都能被確認(rèn)接收。
原因三:避免資源浪費(fèi)
如果只有[兩次握手],當(dāng)客戶端發(fā)生的SYN報文在網(wǎng)絡(luò)中阻塞,客戶端沒有收到ACK報文,就會重新發(fā)送SYN,由于沒有第三次握手,服務(wù)端不清楚客戶端是否收到了自己回復(fù)的ACK報文,所以服務(wù)端每收到一個SYN就只能先主動建立一個連接,這會造成什么情況呢?
如果客戶端發(fā)送的SYN報文在網(wǎng)絡(luò)中阻塞了,重復(fù)發(fā)送多次SNY報文,那么服務(wù)端在收到請求后就會建立多個冗余的無效鏈接,造成資源浪費(fèi)。(因?yàn)閮纱挝帐值那闆r下,服務(wù)端在接收到SYN報文后就會建立連接)
這里兩次握手是假設(shè)「由于沒有第三次握手,服務(wù)端不清楚客戶端是否收到了自己發(fā)送的建立連接的?
ACK
?確認(rèn)報文,所以每收到一個?SYN
?就只能先主動建立一個連接」這個場景。
結(jié)論
TCP建立連接時,通過三次握手能夠防止歷史連接的建立,能減少雙方不必要的資源開銷,能幫助雙方同步初始化序列號。序列號能夠保證數(shù)據(jù)包不重復(fù)、不丟棄和按序傳輸。文章來源:http://www.zghlxwxcb.cn/news/detail-582559.html
不使用兩次握手和四次握手的原因:文章來源地址http://www.zghlxwxcb.cn/news/detail-582559.html
- 兩次握手:無法防止歷史連接的建立,會造成雙方資源的浪費(fèi),無法可靠的同步雙方序列號
- 四次握手:三次握手就已經(jīng)理論上最少可靠連接建立,所以不需要使用更多的通信次數(shù)。
到了這里,關(guān)于(學(xué)習(xí)筆記-TCP連接建立)TCP 為什么是三次握手?不是兩次、四次?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!