问题
知乎上看到的一个有意思的问题,TCP握手中,客户端第三次ack比数据包晚到会发生什么事情?下面的回答中看出部分答者对TCP协议理解的不够深入,作者通过packetdrill工具模拟重现这一现象,看看系统中是怎么实现的!
先看结论
结论:只要第三个包的ack序列号正确(即和不带数据的第三次ack序列号相同)的话,可以正常连接
packetdrill复现
下面是使用packetdrill工具进行模拟场景:
以下抓包中 192.0.2.1 为客户端,另一个为服务端(192.0.2.1为stap在系统中生成的ip,作为客户端)
正常情况
先看看正常场景模拟:
1 | --tolerance_usecs=1000000 |
tcpdump查看交互:
1 | [root@0xfe.com.cn ~] |
异常情况,第三次ack晚到
复现模拟乱序过程:
- pktdrill脚本更换收到的顺序如下:
1 | --tolerance_usecs=1000000 |
2.抓包结果如下:
1 | 14:21:48.191298 IP 192.0.2.1.38177 > 192.168.171.254.webcache: Flags [S], seq 0, win 32792, options [mss 1000,nop,wscale 7], length 0 |
可以看到,当这种情况下,服务端会发送RST重置socket。细心的朋友可能会发现,上面构造的第四个包的ack号是0,但是正常的应该是1,那我们修改下试试:
修改后的脚本:
1 | --tolerance_usecs=1000000 |
测试能正常连接:
1 | 14:36:52.761193 IP 192.0.2.1.35618 > 192.168.150.129.webcache: Flags [S], seq 0, win 32792, options [mss 1000,nop,wscale 7], length 0 |
只要数据包的ack是正确的,第三个ack是先收到,还是后收到,还是直接丢弃,均不影响连接的建立,后端也不会进行重试。正常情况握手后的第一个数据包的ack和第三次握手的ack也相同,所以没什么影响。后续收到了之后,进行ack重传即可。
赞赏支持一下