1.TCP為什么三次握手而不是兩次握手
1.防止已失效的連接請求又傳送到服務(wù)器端,因而產(chǎn)生錯誤。
不幸的是, 這種解釋是不準(zhǔn)確的,TCP 采用三次握手的原因其實非常簡單, 遠(yuǎn)沒有大部分博客所描述的那樣云山霧繞。為了實現(xiàn)可靠數(shù)據(jù)傳輸,TCP 協(xié)議的通信雙方, 都必須維護(hù)一個序列號, 以標(biāo)識發(fā)送出去的數(shù)據(jù)包中, 哪些是已經(jīng)被對方收到的。三次握手的過程即是通信雙方相互告知序列號起始值, 并確認(rèn)對方已經(jīng)收到了序列號起始值的必經(jīng)步驟。如果只是兩次握手, 至多只有連接發(fā)起方的起始序列號能被確認(rèn), 另一方選擇的序列號則得不到確認(rèn)。
位碼即tcp標(biāo)志位,有6種標(biāo)示:
① SYN(synchronous建立聯(lián)機(jī));
② ACK(acknowledgement 確認(rèn))
③ PSH(push傳送)
④ FIN(finish結(jié)束)
⑤ RST(reset重置)
⑥ URG(urgent緊急)
Sequence number(順序號碼) //Acknowledge number(確認(rèn)號碼)
第一次握手:主機(jī)A發(fā)送位碼為SYN=1,隨機(jī)產(chǎn)生seq number=1234567的數(shù)據(jù)包到服務(wù)器,主機(jī)B由SYN=1知道,A要求建立聯(lián)機(jī);
第二次握手,主機(jī)B收到請求后要確認(rèn)聯(lián)機(jī)信息,向A發(fā)送ack number=(主機(jī)A的seq+1),SYN=1,ACK=1,隨機(jī)產(chǎn)生seq number=7654321的包;
第三次握手:主機(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則連接建立成功。
sequence number:表示的是我方(發(fā)送方)這邊,這個packet的數(shù)據(jù)部分的第一位應(yīng)該在整個data stream中所在的位置。(注意這里使用的是“應(yīng)該”。因為對于沒有數(shù)據(jù)的傳輸,如ACK,雖然它有一個seq,但是這次傳輸在整個data stream中是不占位置的。所以下一個實際有數(shù)據(jù)的傳輸,會依舊從上一次發(fā)送ACK的數(shù)據(jù)包的seq開始)
acknowledge number:表示的是期望的對方(接收方)的下一次sequence number是多少。
注意,SYN/FIN的傳輸,雖然沒有data,但是會讓下一次傳輸?shù)膒acket seq增加一,但是,ACK的傳輸,不會讓下一次的傳輸packet seq加一。
題外話
有一位讀者關(guān)注到了三次握手中, 序列號變化的問題, 讓筆者臨時想起了曾經(jīng)困擾自己的一個問題
為什么三次握手最后一次握手中, 在上面的示意圖中回復(fù)的seq = x+1 。
acknowledgement number 的作用是向?qū)Ψ奖硎?,我期待收到的下一個序號。如果你向?qū)Ψ交貜?fù)了ack = 31, 代表著你已經(jīng)收到了序號截止到30的數(shù)據(jù),期待的下一個數(shù)據(jù)起點是31 。
TCP 協(xié)議規(guī)定SYN報文雖然不攜帶數(shù)據(jù), 但是也要消耗1個序列號, 所以前兩次握手客戶端和服務(wù)端都需要向?qū)Ψ交貜?fù)x+1 或y+1 。
值得注意的是, 如上圖所說, 最后一次握手在默認(rèn)不攜帶數(shù)據(jù)的情況下, 由于SYN 不是1 , 是不消耗序列號的。所以三次握手結(jié)束后, 客戶端下一個發(fā)送的報文中seq 依舊是x+1, 示意圖如下
注意到, 上圖第四步發(fā)送的seq 和第三次握手的seq 是一樣的, 體現(xiàn)了最后一次握手, 默認(rèn)不消耗序列號的特點。
四次揮手
四次握手是指終止TCP連接協(xié)議時,需要在客戶端和服務(wù)器之間發(fā)送四個包
第一次揮手:主動關(guān)閉方發(fā)送第一個包,其中FIN標(biāo)志位為1,發(fā)送順序號seq為X。
第二次揮手:被動關(guān)閉方收到FIN包后發(fā)送第二個包,其中發(fā)送順序號seq為Z,接收順序號ack為X+1。
第三次揮手:被動關(guān)閉方再發(fā)送第三個包,其中FIN標(biāo)志位為1,發(fā)送順序號seq為Y,接收順序號ack為X。
第四次揮手:主動關(guān)閉方發(fā)送第四個包,其中發(fā)送順序號為X,接收順序號為Y。至此,完成四次揮手。
超時重傳指的是,發(fā)送數(shù)據(jù)包在一定的時間周期內(nèi)沒有收到相應(yīng)的ACK,等待一定的時間,超時之后就認(rèn)為這個數(shù)據(jù)包丟失,就會重新發(fā)送。這個等待時間被稱為RTO.
深入討論:
1、為什么建立連接協(xié)議是三次握手,而關(guān)閉連接卻是四次握手呢?
建立連接時,ACK和SYN可以放在一個報文里來發(fā)送。而關(guān)閉連接時,被動關(guān)閉方可能還需要發(fā)送一些數(shù)據(jù)后,再發(fā)送FIN報文表示同意現(xiàn)在可以關(guān)閉連接了,所以它這里的ACK報文和FIN報文多數(shù)情況下都是分開發(fā)送的。
2、為什么TIME_WAIT狀態(tài)還需要等2MSL后才能返回到CLOSED狀態(tài)?
兩個存在的理由:1、無法保證最后發(fā)送的ACK報文會一定被對方收到,所以需要重發(fā)可能丟失的ACK報文。2、關(guān)閉鏈接一段時間后可能會在相同的IP地址和端口建立新的連接,為了防止舊連接的重復(fù)分組在新連接已經(jīng)終止后再現(xiàn)。2MSL足以讓分組最多存活msl秒被丟棄。
3、為什么必須是三次握手,不能用兩次握手進(jìn)行連接?
記住服務(wù)器的資源寶貴不能浪費! 如果在斷開連接后,第一次握手請求連接的包才到會使服務(wù)器打開連接,占用資源而且容易被惡意攻擊!防止攻擊的方法,縮短服務(wù)器等待時間。兩次握手容易死鎖。如果服務(wù)器的應(yīng)答分組在傳輸中丟失,將不知道S建立什么樣的序列號,C認(rèn)為連接還未建立成功,將忽略S發(fā)來的任何數(shù)據(jù)分組,只等待連接確認(rèn)應(yīng)答分組。而S在發(fā)出的分組超時后,重復(fù)發(fā)送同樣的分組。這樣就形成了死鎖。
鏈接:https://www.cnblogs.com/my-first-blog-lgz/p/14788810.html
-
服務(wù)器
+關(guān)注
關(guān)注
12文章
9234瀏覽量
85642 -
TCP
+關(guān)注
關(guān)注
8文章
1372瀏覽量
79142
原文標(biāo)題:深度解析TCP三次握手工作原理
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論