TCP協議中的seq/ack序號是如何變化的?


本文出自 https://www.jianshu.com/p/15754b4e9458

作者寫得很棒,轉載用於學習參考,方便查閱,尊重原創 !

看完這篇文章徹底明白了seq和ack的變化過程,感謝原創作者大大!

原文如下:

這里提供了截取出來的一次client端和server端TCP包的交互過程。建議將圖單獨放到一台設備、或者打印出來查看,以便不斷核對下述內容。

 
TCP數據包交換過程

再開始分析之前,還需要論述一下seq、ack表示什么意思,應該以什么樣的角度去理解這兩個序列號。

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

上面這幾條原則第一次讀會有些抽象,可以先繼續往下讀分析過程,再回過頭來查看這個三個原則。

1、

  • seq:client端第一次發送packet,即:first-way handshake。所以按照上面的准則,它的數據應該從第一個開始,也即是第0位開始,所以seq為0。
  • ack:而server端之前並未發送過數據,所以期望的是server端回傳時的packet的seq應該從第一個開始,即是第0位開始,所以ack為0。

2、

  • seq:server端第一次發送packet,即:second-way handshake。所以,這個packet的seq為0。
  • ack:由於在【1】中接收到的是client端的SYN數據包,且它的seq為1,所以client端會讓它自己的seq增加1。由此可預計(expect),client端的下一次packet傳輸時,它的seq是1(0增加1)。所以,ACK為1。

3、

  • seq:third-way handshake。上一次發送時為【1】,【1】中seq為0且為SYN數據包,所以這一次的seq為1(0增加1)。
  • ack:上次接收到時為【2】,【2】中seq為0,且為SYN數據包(雖然在flag上同時設定為SYN/ACK,但只要flag是SYN,就會驅使seq加一),所以可預計,server端下一次seq為1(0增加1)。

4、

  • seq:上一次發送時為【1】,【1】中seq為0且為SYN數據包,所以這一次的seq為1(0增加1)。
  • ack:上次接收到時為【2】,【2】中seq為0,且為SYN數據包,所以可預計,server端下一次seq為1(0增加1)。

5、

  • seq:上一次發送時為【2】,【2】中seq為0,且為SYN數據包,所以這一次的seq為1(0增加1)。
  • ack:上一次接收時為【4】,【4】中的seq為1,數據包的長度為725,所以可以預計,下一次client端的seq為726(1+725)。

6、

  • seq:上一次發送時為【5】,【5】中seq為1,但【5】為ACK數據包,所以數據長度為0且不會驅使seq加1,所以這一次的seq為1(1+0)。
  • ack:上一次接收時為【4】,【4】中的seq為1,數據包的長度為725,所以可以預計,下一次client端的seq為726(1+725)。

7、

  • seq:上一次發送時為【4】,【4】中seq為1,數據包長度為725,所以這一次的seq為726(1+725)。
  • ack:上一次接收時為【6】,【6】中seq為1,且數據長度為1448,所以可以預計,下一次server端的seq為1449(1+1448)。

8、

  • seq:上一次發送時為【6】,【6】中seq為1,數據包長度為1448,所以這一次的seq為1449(1+1448)。
  • ack:上一次接收時為【7】,【7】中seq為726,數據包為ACK、即數據為0,所以可以預計,下一次client端的seq為726(726+0)。

9、

  • seq:上一次發送時為【7】,【7】中seq為726,數據包為ACK、即長度為0, 所以這一次seq為726(726+0)。
  • ack:上一次接收時為【8】,【8】中seq為1449,數據包長度為1448,所以可以預計,下一次server端的seq為2897(1449+1448)。

10、

  • seq:上一次發送時為【8】,【8】中seq為1449,且數據包長度為1448,所以這一次seq為2897(1449+1448)。
  • ack:上一次接收時為【9】,【9】中seq為726,數據包為ACK、即數據為0,所以可以預計,下一次client端的seq為726(726+0)。

剩下的7個packet可以留作練習題自己分析。可以看到的是,從【7】開始,client端這邊就只負責做響應,發送ACK數據包,而並沒有實際的數據發送到server端。所以,從【7】開始,所有的ACK數據包的seq都是相同的726,因為ACK不像SYN/FIN可以讓seq增加,所以發送再多的ACK包都只能讓seq原地踏步。

丟包驗證

由此可以看到,無論對於client端還是server端,這一次剛收到的對方的packet的seq,一定要和最后一次發送時的packet的ack相等。

因為最后一次發送時的packet的ack,是對下一次接收的packet的seq做的預測。如果兩者不等,則表明中途有數據包丟失了!



作者:kid551
鏈接:https://www.jianshu.com/p/15754b4e9458
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

 


免責聲明!

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



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