【问题标题】:Is there a way to tell the OS to drop any buffered outgoing TCP data?有没有办法告诉操作系统丢弃任何缓冲的传出 TCP 数据?
【发布时间】:2011-02-01 02:32:08
【问题描述】:

我在基于 TCP 的客户端软件中遇到了一个有趣/烦人的情况,它是这样的:

  1. 我的客户端进程在笔记本电脑上运行,它通过 TCP 连接到我的服务器进程(通过 LAN 在另一台机器上运行)
  2. 不负责任的用户在客户端传输 TCP 数据时将以太网电缆从笔记本电脑中拔出
  3. 客户端进程继续使用一些额外的 TCP 数据调用 send(),填满操作系统的 SO_SNDBUF 缓冲区,直到...
  4. (通过 MacOS/X 的 SCDynamicStoreCallback 功能)通知客户端进程以太网接口已关闭,并通过调用其 TCP 套接字上的 close() 来响应
  5. 两到五秒过去了...
  6. 用户重新插入以太网电缆
  7. 通知客户端进程接口已备份,并自动重新连接到服务器

这一切都很好......除了通常还有一个不需要的步骤 8,即:

.8。在第 4 步中关闭()的 TCP 套接字恢复(!)并发送该套接字的内核出站数据缓冲区中的剩余数据。发生这种情况是因为操作系统会在释放套接字之前尝试传递所有出站 TCP 数据……通常是一件好事,但在这种情况下,我宁愿不要发生这种情况。

那么,问题是,有没有办法告诉 TCP 层将数据丢弃在其 SO_SNDBUF 中?如果是这样,我可以在步骤 4 中关闭()死套接字之前进行该调用,并且我不必担心在旧套接字被废弃后来自旧套接字的僵尸数据到达服务器。

【问题讨论】:

  • 在我看来,这听起来像是 Apple 实施中的一个错误。您可以将套接字的 SO_LINGER 设置为 0,这将消除调用 close 和实际发生 close 之间的等待。在close 成功后,不应再传输数据。 unix.org/single_unix_specification_v3
  • @Jerry Coffin:不应接受通过send()调用传输的数据,但仍应传输先前写入的数据。
  • @caf:SUS 似乎不同意:“如果 fildes 指的是套接字,则 close() 将导致套接字被销毁。如果套接字处于连接模式,并且 SO_LINGER为具有非零延迟时间的套接字设置了选项,并且套接字具有未传输的数据,则 close() 将阻塞当前的延迟时间,直到传输所有数据。逗留时间到期后,套接字被销毁 - 期间。没有更多数据被接受传输。
  • @Jerry Coffin:并不是说套接字立即被销毁。如果SO_LINGER 没有设置,那只是意味着close() 不会阻塞。 POSIX 更清楚地说明了这一点 - “如果未指定 SO_LINGER,并且发出了 close(),系统会以允许调用线程尽快继续的方式处理调用。”

标签: c sockets tcp


【解决方案1】:

这(从两个不同的 TCP 连接接收的数据没有相互排序)是 TCP/IP 的基本属性。您不应该尝试通过清除发送缓冲区来解决它 - 这很脆弱。相反,您应该修复应用程序以在应用程序层处理这种可能性。

例如,如果您在服务器端收到一个您认为已经连接的客户端的新连接,您可能应该断开现有连接。

此外,该过程的第 4 步有点可疑。实际上,您应该等到 TCP 报告错误(或连接上发生应用程序级超时) - 正如您所注意到的,如果物理断开只是短暂的,TCP 将恢复。

【讨论】:

  • 嗯,该解决方案的一个问题是服务器允许来自单个客户端的多个连接,因此删除现有连接会导致问题。关于等待 TCP 报告错误:这是最初的设计,但客户端是现场声音控制器控制系统的一部分,因此等待 30-90 秒让 TCP 超时确实不是我们的选择。
  • @Jeremy Friesner:然后您需要做一些更复杂的事情 - 让客户端为每个连接发送一个标识符号和/或每个命令的序列号/时间戳,以便服务器可以检测陈旧的连接或乱序命令(最好在应用程序级别处理)。如果您的应用程序使得来自客户端的旧命令完全被新命令取代,那么听起来 UDP 可能更合适。
【解决方案2】:

如果您想在第 4 步关闭套接字时丢弃任何等待传输的数据,则只需在关闭前将 SO_LINGER 设置为 0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多