我在Android设备上使用tcpdump捕获了这些数据包(linux 3.4.39),这些数据包在HTTP GET流中:
1 385.447794服务器 - >客户:SEQ 12517,LEN 100
2 385.498345客户 - >服务器:SEQ 3086,LEN 0,ACK 12617
3 385.497836服务器 - >客户:SEQ 12617,LEN 1348
4 385.498644客户 - >服务器:[DUP ACK] SEQ 3086,LEN 0,ACK 12617
5 385.498735服务器 - >客户:SEQ 13965,LEN 619
6 385.498978客户 - >服务器:[Dup ACK] SEQ 3086,LEN 0,ACK 12617
7 385.718843服务器 - >客户:[Retrans] SEQ 13965,LEN 619
8 385.719280客户 - >服务器:[DUP ACK] SEQ 3086,LEN 0,ACK 12617
9 385.733230服务器 - >客户:[Retrans] SEQ 12617,LEN 1348
10 385.733602客户 - >服务器:SEQ 3086,LEN 0,ACK 14584
11 385.909921服务器 - >客户:[Retrans] SEQ 12617,LEN 1348
12 385.910449客户 - >服务器:[DUP ACK] [窗口更新] SEQ 3086,LEN 0,ACK 14584
13 388.031541客户 - >服务器:SEQ 832,LEN 0,ACK 4192,FIN
14 388.031681客户 - >服务器:SEQ 3086,LEN 0,ACK 14584,FIN
客户端是我的设备。
是什么导致客户端发送这些重复的TCP ACK?
更新:
为什么客户端在收到后续TCP数据包(#3)后发送之前的DUP ACK(#4)?
感谢。
答案 0 :(得分:2)
是什么导致客户端发送这些重复的TCP ACK?
receiver (client)
将ACK#
作为SEQ#
的{{1}}发送给sender (server)
。
在您的示例中,服务器已发送:
1 385.447794 Server -> Client: SEQ 12517, LEN 100
client
收到它,然后通过SEQ#
12517+100 = 12617
ACK = 12617
的数据包
2 385.498345 Client -> Server: SEQ 3086, LEN 0, ACK 12617
如果数据包中包含SEQ#
12617
:
3 385.497836 Server -> Client: SEQ 12617, LEN 1348
丢失且receiver
未收到,receiver
将发送duplicate ACK
,这表示sender
重新传输数据包(表明数据包已丢失。)
4 385.498644 Client -> Server: [DUP ACK] SEQ 3086, LEN 0, ACK 12617
为什么客户端在收到后续TCP数据包(#3)后发送上一个DUP ACK(#4)?
因为SEQ#12617
的数据包似乎在通道中丢失,client
没有收到这些数据包。因此,重复ACK 12617
表示server
重新传输它。
我想知道Linux内核读取数据包和发送ACK是否在不同的线程中进行处理?
它不能是不同的线程,因为线程根据它收到的ACKS#
生成SEQ#
。所以,它不能是两个不同的线程。即使它们是,也必须等待来自另一方的信息(同步)。