TCP 连接中的 FIN 与 RST

Posted

技术标签:

【中文标题】TCP 连接中的 FIN 与 RST【英文标题】:FIN vs RST in TCP connections 【发布时间】:2012-10-14 12:42:11 【问题描述】:

据我了解,关闭 TCP 连接有两种方式:

发送 FIN 标志 发送 RST 标志

RST 会导致连接立即终止,而在 FIN 中您会得到确认。

我是否理解这一点,两者之间还有其他区别吗?这两个标志可以一起使用吗?

【问题讨论】:

【参考方案1】:

FIN 说:“我已经和你谈完了,但我仍然会听你说的一切,直到你说你已经完成了。”

RST 说:“没有对话。我不会说什么,也不会听你说什么。”

如果您的 TCP 连接持久且流量很小,RST 很有用。如果其中一台计算机重新启动,它会忘记连接,而另一台计算机在发送另一个数据包后立即获得 RST。

【讨论】:

【参考方案2】:

以下情况会发送FIN或RST

你的进程关闭了套接字

当您的进程退出而不关闭套接字时,操作系统正在执行资源清理。

如果你的进程调用close(),FIN会默认从关闭端发送(注意:你可以设置socket选项SO_LINGER让它发送RST而不是FIN)

如果您的进程在没有关闭套接字的情况下退出,内核将关闭 tcp 连接并为您的进程进行清理。可以发送 FIN 或 RST。如果您的接收队列中有数据,则会发送 RST。否则,将发送 FIN。

您可以通过 tcp.c 中的 tcp_close() 循环了解更多详细信息。(我使用的是 redhat 分支的 kernel-2.6.32-573.7.1)

【讨论】:

【参考方案3】:

来自 RFC 1122,每个人都在引用,但实际上并未引用, 反对我:

一个 TCP 连接可能会以两种方式终止:(1) 正常的 使用 FIN 握手的 TCP 关闭序列,以及 (2) “中止” 其中一个或多个 RST 段被发送并且 连接状态立即被丢弃。

两者不能同时使用。这个概念甚至没有意义。

可以通过我不会在这里描述的诡计来关闭使用 RST 而不是 FIN 的 TCP 连接,但这是一个愚蠢的想法,这就是我没有记录它的原因。一方面,传输中的所有待处理数据都会丢失。

【讨论】:

@downvoter 请向我解释您对此答案的问题。 "不能同时使用两者。"这在技术上可能的。只是,正如您所说,“这个概念甚至没有开始有意义”。 (虽然我不是那个投反对票的人)。 RST 不一定表示错误情况。这可能只是意味着 RST 的发送者不想再收到您的消息,并且不一定会处理仍然为连接缓冲的任何数据。将两个标志设置在一起对于一半的连接是多余的,但不是禁止的。在某些情况下,RST 在 FIN 之后不久就出现了,这当然并不少见。 @Dave RST 丢弃为连接缓冲的所有数据,这些数据本身不再存在。发件人没有处理或不处理它的选项。 “同时”与“不久之后”不同。 @EJP - RST 在 RFC 793 和 1122 中有多种用途。其中之一就是您所描述的 - 表示“不存在此类连接”或不再存在。

以上是关于TCP 连接中的 FIN 与 RST的主要内容,如果未能解决你的问题,请参考以下文章

TCP半连接对端不断开,试试用RST

tcp三次握手

【tcp】TCP报文段中URG和PSH的区别

TCP的几个状态TIPS:

TCP的几个状态TIPS:

TCP状态详解