本文出自 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
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。