TCP程序在收到RST或FIN后被动关闭TCP连接之前会检查缺失的数据包吗?

3
如果A和B之间建立了TCP连接,A发送一些数据包,然后发送TCP RST(或TCP FIN/ACK)来关闭连接,你觉得怎么样?
     PKT1, PKT2, PKT3, TCP_RST

或者
     PKT1, PKT2, PKT3, TCP_FIN/ACK

但数据包的到达顺序不正确

    PKT1, TCP_RST(or TCP_FIN/ACK), PKT2, PKT3

那么B会有什么反应呢?

根据TCP_RST和TCP_FIN/ACK的序列号, B知道有一些数据包丢失了(PKT2和PKT3), 它会在关闭连接之前等待PKT2和PKT3的到来, 还是在收到TCP_RST(或TCP_FIN/ACK)后立即关闭连接?

谢谢。

2个回答

1
TCP协议会在将数据包传递到更高层之前对其进行重新排序。这意味着它会根据序列号等待乱序的数据包,如有必要会请求重传,并在关闭连接前等待最后一个确认消息。
您可以在此处找到TCP状态图: http://www.ssfnet.org/Exchange/tcp/tcpTutorialNotes.html#ST

如果 PKT2 和 PKT3 丢失了,由于 A 已经半关闭,A 将不会重新传输 PKT2 和 PKT3,然后 B 仍将等待 PKT2 和 PKT3,并忽略 RST(或 FIN/ACK)吗? - misteryes
即使A发送了FIN,如果被要求这样做,它仍会向B发送重传。只有当从B收到ACK时,A才会关闭。当A和B都决定关闭连接,并且每个人都收到了FIN数据包的ACK时,套接字将关闭。 - PurpleAlien
只是澄清一件事:如果A发送RST,则连接将立即重置并且数据丢失。这是干扰网络的可能攻击向量。但是在正常情况下,不会发送RST。例如,当主机B重新启动并且A继续发送数据包时,它可能会发生。然后,B可以发送RST数据包,因为它没有任何关于传入数据的上下文。如果在正常情况下发生,那么只有在之前发送的FIN得到确认时才会发送。 - PurpleAlien
抱歉,最后一个问题:如果B已经接收了一些数据包并且它们在接收缓冲区中(尚未传递到应用层),此时收到RESET数据包,B会丢弃接收缓冲区中的数据吗? - misteryes
是的,在那种情况下它会生效。RST 将指示另一端出现了问题,现在该缓冲区中的任何数据都不再相关。这就是为什么如果您可以制造虚假的 RST 数据包来中断正常的网络操作,这将是一种有效的攻击方式。 - PurpleAlien

0
TCP保证顺序。这包括EOS的顺序。它必须在所有数据之后传递。

我不明白你的意思。EOS是什么?必须交付什么?问题在于如果RST或FIN/ACK在数据之前到达。 - misteryes
问题在于如果RST或FIN/ACK先于数据到达,这时候B不会为A的FIN发送ACK,直到B有所有的序列号所表示的数据。 - PurpleAlien
EOS是流的结束。它由传入的FIN引起,并显示为recv()返回零。在recv()读取所有数据之前,不会发生这种情况。然而,传入的RST会导致任何未决数据的丢失,并显示为recv()返回-1,其中errno == ECONNRESET - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接