104

我想我理解该选项的正式含义。在我现在处理的一些遗留代码中,使用了该选项。客户抱怨 RST 是从其一侧对 FIN 的响应,因为它从其一侧关闭连接。

我不确定我是否可以安全地移除它,因为我不知道什么时候应该使用它。

您能否举例说明何时需要该选项?

4

8 回答 8

207
于 2012-10-26T14:29:46.287 回答
90

将超时设置为零的典型原因SO_LINGER是避免大量连接处于该TIME_WAIT状态,从而占用服务器上的所有可用资源。

当 TCP 连接完全关闭时,发起关闭的一端(“主动关闭”)以连接TIME_WAIT停留几分钟而告终。因此,如果您的协议是服务器启动连接关闭的协议,并且涉及大量短期连接,那么它可能容易受到此问题的影响。

不过,这不是一个好主意 -TIME_WAIT存在是有原因的(以确保来自旧连接的杂散数据包不会干扰新连接)。如果可能的话,将您的协议重新设计为客户端启动连接关闭的协议是一个更好的主意。

于 2010-09-21T12:18:22.333 回答
18

当 linger 开启但超时为零时,TCP 堆栈在关闭连接之前不会等待发送待处理的数据。数据可能因此而丢失,但通过以这种方式设置 linger ,您将接受这一点并要求立即重置连接,而不是正常关闭连接。这会导致发送 RST 而不是通常的 FIN。

感谢 EJP 的评论,请参阅此处了解详细信息。

于 2010-09-21T07:15:31.170 回答
7

是否可以安全地删除代码中的 linger 取决于应用程序的类型:它是“客户端”(打开 TCP 连接并首先主动关闭它)还是“服务器”(监听 TCP 打开和在对方发起关闭后关闭它)?

如果您的应用程序具有“客户端”的风格(首先关闭)并且您启动和关闭大量与不同服务器的连接(例如,当您的应用程序是监控大量不同服务器的可访问性时)您的应用程序存在所有客户端连接都卡在 TIME_WAIT 状态的问题。然后,我建议将超时值缩短到比默认值更小的值,以便仍然正常关闭,但更早地释放客户端连接资源。我不会将超时设置为 0,因为 0 不会用 FIN 正常关闭,但会用 RST 中止。

如果您的应用程序具有“客户端”的风格,并且必须从同一服务器获取大量小文件,那么您不应该为每个文件启动一个新的 TCP 连接并最终在 TIME_WAIT 中出现大量客户端连接,但是保持连接打开并通过同一连接获取所有数据。可以而且应该删除逗留选项。

如果您的应用程序是“服务器”(关闭第二个作为对等点关闭的反应),则在 close() 时,您的连接将正常关闭,并且由于您没有进入 TIME_WAIT 状态而释放资源。不应使用灵儿。但是,如果您的服务器应用程序有一个监控进程来检测长时间闲置的非活动打开连接(“长”将被定义),您可以从您的身边关闭这个非活动连接 - 将其视为一种错误处理 - 中止关闭。这是通过将 linger timeout 设置为 0 来完成的。close() 然后会向客户端发送一个 RST,告诉他你很生气 :-)

于 2018-01-11T09:16:55.813 回答
1

在服务器中,您可能希望在断开行为不端的客户端时发送RST而不是发送。FIN跳过服务器中FIN-WAITTIME-WAIT套接字状态,这可以防止耗尽服务器资源,因此可以防止这种拒绝服务攻击。

于 2019-12-19T16:09:07.907 回答
1

我喜欢 Maxim 的观察,即 DOS 攻击会耗尽服务器资源。在没有真正恶意的对手的情况下也会发生这种情况。

一些服务器必须处理“无意 DOS 攻击”,这种攻击发生在客户端应用程序存在连接泄漏错误时,它们会不断为发送到服务器的每个新命令创建新连接。然后,如果它们遇到 GC 压力,可能最终会关闭它们的连接,或者连接最终会超时。

另一种情况是“所有客户端都具有相同的 TCP 地址”的情况。然后客户端连接只能通过端口号来区分(如果它们连接到单个服务器)。如果客户端出于任何原因开始快速循环打开/关闭连接,它们可能会耗尽(客户端地址+端口,服务器 IP+端口)元组空间。

因此,我认为最好建议服务器在看到大量处于 TIME_WAIT 状态的套接字时切换到 Linger-Zero 策略——尽管它不能修复客户端行为,但可能会减少影响。

于 2020-01-13T23:30:43.003 回答
0

服务器上的侦听套接字可以使用时间为 0 的 linger 来访问立即绑定回套接字并重置尚未完成连接的任何客户端。TIME_WAIT 仅在您拥有多路径网络并且可能以错误排序的数据包结束或以其他方式处理奇怪的网络数据包排序/到达时间时才有意义。

于 2020-02-28T23:57:03.107 回答
0

我刚刚在websockets RFC (RFC 6455)中看到,它明确指出服务器应该首先调用close()TCP 套接字(!)

我很敬畏,因为事实上我在这个线程中持有@mgd 的答案/帖子,而 RFC 显然反对这一点。但是,也许这将是可以接受将逗留时间设置为 0 的情况。

底层 TCP 连接,在大多数正常情况下,应该首先由服务器关闭,以便它保持 TIME_WAIT 状态而不是客户端

我很想听听对此的任何想法/见解。

于 2021-07-14T22:52:30.837 回答