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

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

TCP數據包交換過程

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

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

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

一、it

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

二、class

  • 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。

三、stream

  • 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)。

四、cli

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

五、im

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

六、數據

  • 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)。

七、img

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

八、

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

九、

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

十、

  • 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作的預測。若是二者不等,則代表中途有數據包丟失了!

相關文章
相關標籤/搜索