什么时候需要 TCP 选项 SO_LINGER (0)?

2024-01-06

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

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

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


对于我的建议,请阅读最后一节:“何时使用超时为 0 的 SO_LINGER”.

在我们开始之前,先听一个关于以下内容的小讲座:

  • 正常 TCP 终止
  • TIME_WAIT
  • FIN, ACK and RST

正常 TCP 终止

正常的 TCP 终止序列如下所示(简化):

我们有两个对等点:A 和 B

  1. A calls close()
  • A sends FIN to B
  • A 进入FIN_WAIT_1 state
  1. B 收到FIN
  • B sends ACK to A
  • B 进入CLOSE_WAIT state
  1. A 收到ACK
  • A 进入FIN_WAIT_2 state
  1. B calls close()
  • B sends FIN to A
  • B 进入LAST_ACK state
  1. A 收到FIN
  • A sends ACK to B
  • A 进入TIME_WAIT state
  1. B 收到ACK
  • 乙去CLOSED状态 – 即从套接字表中删除

时间的等待

因此发起终止的对等方 – 即调用close()首先 – 最终将在TIME_WAIT state.

要了解为什么TIME_WAIT状态是我们的朋友,请阅读 Stevens 等人的《UNIX 网络编程》第三版(第 43 页)中的 2.7 节。

但是,如果有大量套接字,这可能会出现问题TIME_WAIT服务器上的状态,因为它最终可能会阻止接受新连接。

为了解决这个问题,我看到很多人建议在调用之前将 SO_LINGER 套接字选项设置为超时 0close()。然而,这是一个糟糕的解决方案,因为它会导致 TCP 连接因错误而终止。

相反,请设计您的应用程序协议,以便始终从客户端发起连接终止。如果客户端始终知道何时读取了所有剩余数据,则它可以启动终止序列。举个例子,浏览器从Content-Length当 HTTP 标头已读取所有数据并可以发起关闭时。 (我知道在 HTTP 1.1 中它会保持打开状态一段时间以便可能重用,然后关闭它。)

如果服务器需要关闭连接,请设计应用程序协议,以便服务器要求客户端调用close().

何时使用超时为 0 的 SO_LINGER

再次,根据《UNIX网络编程》第三版第202-203页,设置SO_LINGER调用前超时为 0close()将导致正常的终止序列not待发起。

相反,对等方设置此选项并调用close()将发送一个RST(连接重置)表示错误情况,这就是另一端的感知方式。您通常会看到诸如“连接被对等方重置”之类的错误。

因此,在正常情况下,设置是一个非常糟糕的主意SO_LINGER调用前超时为 0close()– 从现在开始叫失败的关闭– 在服务器应用程序中。

但是,无论如何,某些情况都需要这样做:

  • 如果服务器应用程序的客户端行为不当(超时、返回无效数据等),则中止关闭可以避免陷入困境CLOSE_WAIT或最终在TIME_WAIT state.
  • 如果您必须重新启动当前具有数千个客户端连接的服务器应用程序,您可以考虑设置此套接字选项以避免数千个服务器套接字TIME_WAIT(当打电话时close()从服务器端),因为这可能会阻止服务器在重新启动后获取新客户端连接的可用端口。
  • 在上述书中的第 202 页,它特别指出:“在某些情况下,需要使用此功能来发送中止关闭。一个例子是 RS-232 终端服务器,它可能会永远挂在CLOSE_WAIT尝试将数据传送到卡住的终端端口,但如果收到错误消息,则会正确重置卡住的端口RST丢弃待处理的数据。”

我会推荐this http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html我相信这篇长文章很好地回答了您的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么时候需要 TCP 选项 SO_LINGER (0)? 的相关文章

  • 链路范围 IPv6 多播数据包突然无法在 MacBook Pro 上路由?

    这是一个有点晦涩的问题 但我很困惑 我想也许有人对这个问题有更多的线索 我的同事已经在他的 MacBook Pro 上成功运行了一个使用 IPv6 多播的内部应用程序几个月了 但今天 Mac 决定停止路由多播数据包 特别是 该程序打印此错误
  • 当 TCP 序列号到达而不是预期时会发生什么情况?

    我正在编写一个程序 使用 libpcap 捕获数据包并重新组装 TCP 流 我的程序只是监视流量 因此我无法控制数据包的接收和发送 我的程序忽略所有非 TCP IP 流量 我根据 ISN 计算下一个预期序列号 然后计算连续的 SEQ 号 我
  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a
  • SQL Server“未找到网络路径”在不同环境中随机且不频繁地发生

    类似 如果不是同一个问题 随机遇到网络路径未找到异常 https stackoverflow com questions 38696448 network path not found exception encountered rando
  • netdb.h 未正确链接

    我正在尝试编译这个程序 如引用的Beej 的网络编程指南第 19 页 include
  • Python UPnP/IGD 客户端实现?

    我正在寻找一个开源实现UPnP http elinux org UPnPPython 中的客户端 更具体地说是它的互联网网关设备 http en wikipedia org wiki Internet Gateway Device Prot
  • 如何使用 Nmap 检索 TCP 和 UDP 端口? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我需要在使用 Nmap 的同一扫描中以尽可能最快的方式检索 TCP 和 UDP 端口 我会尽力解释得更好 如果我使用最常用的命令 nmap 192 1
  • 如何在亚马逊AWS上加载ena驱动程序?

    我正在尝试在 Ubuntu VM 上加载 ena 驱动程序 根据文档 我的虚拟机有vif低性能驱动程序 ubuntu ip 172 31 14 190 ethtool i eth0 driver vif version firmware v
  • 如何以最短的停机时间移交 TCP 侦听套接字?

    虽然这个问题被标记为 EventMachine 任何语言的通用 BSD 套接字解决方案也非常受欢迎 一些背景 我有一个应用程序正在侦听 TCP 套接字 它通过常规的 System V 风格的 init 脚本启动和关闭 我的问题是它需要一些时
  • 如何在 NLog 中记录网络目标的异常

    我正在使用NLog http nlog project org日志框架 并尝试获取任何 UDP 记录器应用程序中显示的异常和堆栈跟踪信息 例如Sentinel http sentinel codeplex com and Log2控制台 h
  • C# 中的 Unix 套接字

    我正在尝试使用 Mono 的 UnixEndPoint 但在使用它之前就失败了 我在 64 位 Windows 7 系统上运行 Xamarind net 4 5 下面是一些代码 证明单一组合不起作用 foreach SocketType s
  • 我可以关闭并重新打开套接字吗?

    我学习了一个使用套接字的例子 在此示例中 客户端向服务器发送请求以打开套接字 然后服务器 侦听特定端口 打开套接字 一切都很好 套接字从双方 客户端和服务器 打开 但我仍然不清楚这个东西有多灵活 例如 客户端是否可以关闭一个打开的 从两端
  • 如何使用 IdTCPClient 等待来自服务器的字符串?

    我的 IdTelnet indy 10 1 有问题 我无法以 Unicode 模式从服务器读取数据 现在我想用 IdTCPClient 编写 telnet 终端 服务器有时发送一行 有时发送越来越多的行 但发送之间没有固定的时间 现在我的问
  • Selector.close() 是否关闭所有客户端套接字?

    我是 nio 套接字的新手 我已经使用 nio 套接字编写了一个服务器 现在我正在尝试编写关闭钩子以确保通过清理资源正常退出 我的问题是Selector close 方法关闭所有客户端套接字 如果没有 请告诉我如何访问所有客户端套接字 而无
  • 错误号:11,资源暂时不可用

    我正在使用 c 套接字来实现可靠的 UDP 协议 我正在使用以下代码在等待确认的套接字上设置超时 我不确定为什么会收到 errno 11 资源暂时不可用 set timer for recv socket struct timeval tv
  • 网络:传输层和网络层之间的区别

    在互联网模型中有四层 链路 gt 网络 gt 传输 gt 应用 我真的不知道网络层和传输层之间的区别 正如我读到的 Transport layer include congestion control flow control reliab
  • 如何从互联网访问本地网络内的服务器

    假设我有一个服务器应用程序在未直接连接到互联网但通过路由器连接的计算机上工作 所以问题是如何从不在内部网络 从互联网 内的另一台计算机连接到该服务器 据我所知 管理员可以配置路由器将指定端口请求重定向到该计算机 但我可以自动执行此操作吗 我
  • 使用 Google App Engine 向防火墙后面的设备发起消息

    我想使用 Google App Engine 向位于防火墙 路由器 NAT 后面的设备发起 http 流量 这些设备将接收来自 GAE 的命令 我可以让设备轮询 GAE 来查找新消息 但这会占用大量流量 或者 我可以尝试永久保持打开连接 但
  • 网络服务发现不是发现服务类型

    我想通过 Android 设备在本地网络中找到服务器 我可以通过使用找到它NSDManager具有服务器服务类型的服务 例如 workstation tcp是服务类型 在我的本地网络中我有一个 无线路由器和无线中继器 两者都有不同的SSID
  • docker 主机 (OSX) 上的关闭端口在内部 docker 网络上保持/报告打开状态

    在 OSX 12 3 上将 Docker 升级到 4 6 0 后 当我停止 PHPStorm 中的 xdebug 监听客户端时 我遇到了一些奇怪的问题 似乎后续请求总是超时 因为 docker 报告 host docker internal

随机推荐