wireshark 抓包:四次挥手为什么只有三次?

import redis

for _ in range(1):
    r = redis.StrictRedis(host='192.168.26.174', port=6379, db=1)

    r.set('ponponon', 'superman')
    print(r.get('ponponon'), type(r.get('foo')))

玩玩 redis ,顺便用 wireshark 抓包看看

但是看到如下的画面:

图片.png

三次招手看起来没有问题,但是为什么挥手只有三次,而不是四次?

192.168.26.174 是跑 redis 的机器
192.168.32.172 是跑客户端程序的机器
阅读 4.1k
3 个回答

如果第2次挥手的ack和第3次挥手的fin之间如果没有数据需要传输的话,是可以合并为一个包(fin+ack)来传输的,也就是压缩成三次挥手

想当然四次挥手属于是背八股文上头了。

TCP 的释放分为正常关闭(三次),半关闭连接(四次)

TCP 连接释放客户端释放:

  • 客户端设置 FIN=1, seq: x
  • 服务器设置 FIN=1, ACK=1,ack: x+1,seq: y(第一步消耗一个字节序号)
  • 客户端设置 ACK=1,seq: x+1, ack: y+1(第二步消耗一个字节的序号)

图片
四步释放 - 半关闭连接:

  • 客户端释放请求 FIN=1, seq: x, ACK=1
  • 服务器还没发完,所以只释放 C->S 方向。所以只回应 ACK=1。seq: y, ack: x+1.
  • 服务器继续发送数据,客户端回 ACK
  • 服务器发完了,可以关闭了。seq: z, ack: x+1, ACK=1, FIN=1
  • 客户端释放接收缓存,seq: x+1, ack: z+1, ACK=1
    图片

这应该是网络不太好,服务器收到了你的中断信号,但服务器发出的ack你确没有收到。然后服务器发送给你中断信号你收到并回复了ACK。你自己多尝试几次,我还真以为是这种情况,还特地去下了wireshark尝试了下,结果没问题。
Dingtalk_20220608161238.jpg

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题