TCP三次握手中SYN,ACK,seq ack的含義


轉至:https://www.cnblogs.com/muyi23333/articles/13841268.html

1.TCP 為什么三次握手而不是兩次握手

1.防止已失效的連接請求又傳送到服務器端,因而產生錯誤。

  不幸的是, 這種解釋是不准確的, TCP 采用三次握手的原因其實非常簡單, 遠沒有大部分博客所描述的那樣雲山霧繞。為了實現可靠數據傳輸, TCP 協議的通信雙方, 都必須維護一個序列號, 以標識發送出去的數據包中, 哪些是已經被對方收到的。 三次握手的過程即是通信雙方相互告知序列號起始值, 並確認對方已經收到了序列號起始值的必經步驟。如果只是兩次握手, 至多只有連接發起方的起始序列號能被確認, 另一方選擇的序列號則得不到確認。

位碼即tcp標志位,有6種標示:

①  SYN(synchronous建立聯機);

②  ACK(acknowledgement 確認)

③  PSH(push傳送)

④  FIN(finish結束)

⑤  RST(reset重置)

⑥  URG(urgent緊急)

Sequence number(順序號碼) //Acknowledge number(確認號碼)

第一次握手:主機A發送位碼為SYN=1,隨機產生seq number=1234567的數據包到服務器,主機B由SYN=1知道,A要求建立聯機;

第二次握手,主機B收到請求后要確認聯機信息,向A發送ack number=(主機A的seq+1),SYN=1,ACK=1,隨機產生seq number=7654321的包;

第三次握手:主機A收到后檢查ack number是否正確,即第一次發送的seq number+1,以及位碼ACK是否為1,若正確,主機A會再發送ack number=(主機B的seq+1),ACK=1,主機B收到后確認seq值與ACK=1則連接建立成功。

sequence number:表示的是我方(發送方)這邊,這個packet的數據部分的第一位應該在整個data stream中所在的位置。(注意這里使用的是“應該”。因為對於沒有數據的傳輸,如ACK,雖然它有一個seq,但是這次傳輸在整個data stream中是不占位置的。所以下一個實際有數據的傳輸,會依舊從上一次發送ACK的數據包的seq開始)

 

acknowledge number:表示的是期望的對方(接收方)的下一次sequence number是多少。

注意SYN/FIN的傳輸,雖然沒有data,但是會讓下一次傳輸的packet seq增加一但是,ACK的傳輸,不會讓下一次的傳輸packet seq加一

題外話

有一位讀者關注到了三次握手中, 序列號變化的問題, 讓筆者臨時想起了曾經困擾自己的一個問題

為什么三次握手最后一次握手中, 在上面的示意圖中回復的 seq = x+1 。

acknowledgement number 的作用是向對方表示,我期待收到的下一個序號。 如果你向對方回復了 ack = 31, 代表着你已經收到了序號截止到30的數據,期待的下一個數據起點是 31 。

TCP 協議規定SYN報文雖然不攜帶數據, 但是也要消耗1個序列號, 所以前兩次握手客戶端和服務端都需要向對方回復 x+1 或 y+1 。

 

 

 

 值得注意的是, 如上圖所說, 最后一次握手在默認不攜帶數據的情況下, 由於SYN 不是 1 , 是不消耗序列號的。 所以三次握手結束后, 客戶端下一個發送的報文中 seq 依舊是 x+1, 示意圖如下

注意到, 上圖第四步發送的 seq 和第三次握手的 seq 是一樣的, 體現了最后一次握手, 默認不消耗序列號的特點。

四次揮手

 

四次握手是指終止TCP連接協議時,需要在客戶端和服務器之間發送四個包

第一次揮手:主動關閉方發送第一個包,其中FIN標志位為1,發送順序號seq為X。

第二次揮手:被動關閉方收到FIN包后發送第二個包,其中發送順序號seq為Z,接收順序號ack為X+1。

第三次揮手:被動關閉方再發送第三個包,其中FIN標志位為1,發送順序號seq為Y,接收順序號ack為X。

第四次揮手:主動關閉方發送第四個包,其中發送順序號為X,接收順序號為Y。至此,完成四次揮手。

超時重傳指的是,發送數據包在一定的時間周期內沒有收到相應的ACK,等待一定的時間,超時之后就認為這個數據包丟失,就會重新發送。這個等待時間被稱為RTO. 

深入討論:

1、為什么建立連接協議是三次握手,而關閉連接卻是四次握手呢?

    建立連接時,ACK和SYN可以放在一個報文里來發送。而關閉連接時,被動關閉方可能還需要發送一些數據后,再發送FIN報文表示同意現在可以關閉連接了,所以它這里的ACK報文和FIN報文多數情況下都是分開發送的。 

2、為什么TIME_WAIT狀態還需要等2MSL后才能返回到CLOSED狀態?

    兩個存在的理由:1、無法保證最后發送的ACK報文會一定被對方收到,所以需要重發可能丟失的ACK報文。2、關閉鏈接一段時間后可能會在相同的IP地址和端口建立新的連接,為了防止舊連接的重復分組在新連接已經終止后再現。2MSL足以讓分組最多存活msl秒被丟棄。 

3、為什么必須是三次握手,不能用兩次握手進行連接?

    記住服務器的資源寶貴不能浪費!  如果在斷開連接后,第一次握手請求連接的包才到會使服務器打開連接,占用資源而且容易被惡意攻擊!防止攻擊的方法,縮短服務器等待時間。兩次握手容易死鎖。如果服務器的應答分組在傳輸中丟失,將不知道S建立什么樣的序列號,C認為連接還未建立成功,將忽略S發來的任何數據分組,只等待連接確認應答分組。而S在發出的分組超時后,重復發送同樣的分組。這樣就形成了死鎖。

參考:https://blog.csdn.net/qq_25948717/article/details/80382766

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM