为什么 TCP 客户端没有收到 ACK 响应,它发送了 FIN 包?

网络工程 tcp 联网
2022-02-26 03:39:21

我使用 WireShark 捕获了 TCP 连接。

您会看到三次握手(1-3)和四次握手(5-8):

在此处输入图像描述

但是,从帧列表中,我有一个关于 TCP 的问题。

您知道 TCP 应该使用 ACK 符号来获取响应,无论是ackforsyn还是ackfor 数据发送。

您会看到第 4 帧,192.168.187.1将消息发送到192.168.187.129[PSH, ACK]。

  1. 但是192.168.187.1没有收到ACK,它发送FIN包到192.168.187.129,为什么?

  2. 第5个包,可以直接发【FIN】包吗?为什么需要[FIN, ACK]?为什么不能发送[FIN]?

2个回答
  1. RFC 793 表明:

一个控制位(finis)占用一个序列号,表示发送方不再发送数据或控制占用序列空间。

如果发送方没有更多数据要发送,它会发送一个设置了其FIN标志的数据包。如果接收者没有收到数据,它会向发送者发送一个副本ACK

所以发送方等待一段时间,如果在这段时间内没有收到FIN或数据的确认,或者收到重复ACK的数据,它将重新发送数据包。

  1. ACK建立连接后始终发送控制标志;正如 RFC 793 所说:

确认号:32 位

如果设置了 ACK 控制位,则该字段包含该段的发送者期望接收的下一个序列号的值。一旦建立连接,它总是被发送。

编辑:所以在没有建立连接之前,可以在没有ACK.

例如,当连接的一侧发送SYN数据包但没有收到任何确认时;在这种情况下,它可以在没有 的情况下发送FIN数据包ACK,因为没有任何东西可以确认它。

RCF793:3.5。关闭连接还表明:

CLOSE 的用户可以继续 RECEIVE,直到他被告知对方也已经 CLOSED。

发送ACK将告诉发送者期望接收哪个序列号,并防止由于ACK丢失而发生的额外重传。


根据@ron-maupin 的评论编辑。

但是192.168.187.1没有收到ACK,它发送FIN包到192.168.187.129,为什么?

显然,192.168.187.1 已完成发送并正在关闭套接字。这是完全正常的。

第5个包,可以直接发【FIN】包吗?为什么需要[FIN, ACK]?为什么不能发送[FIN]?

FIN 和 ACK 组合在一个段中,这也是完全正常的。标志在位字段中发送,因此可以组合它们以避免为每个状态更改发送额外的段。