Linux 上的条件刷新 TCP 套接字

Linux 上的条件刷新 TCP 套接字

每当我将数据写入 TCP 套接字时,它都会等到填充足够的数据,例如:64k(最大数据包大小),然后将数据发送到线路。这会错过另一端正确时间的数据。

当我设置 TCP_NODELAY 时,写入套接字的任何数据都会立即发送到线路。这会减少带宽,因为我们有很多带有 ACK 的小数据包。

我们可以为linux设置一个规则来有条件地清除套接字吗?前任:

if time gap between last sent packet and current data is greater than 100ms send immediately no matter how much data lendth is
else if current data length is bigger than 50kb send immediately no matter how much time gap is
else do nothing, wait some milliseconds for next decision

我不想减少 tcp 缓冲区大小,想修改 linux 刷新数据的方式。

我们可以通过修改linux配置文件来做到这一点吗?或者这必须在每个编写的软件中实现?

任何直接的答案、帮助、解决方案或文章链接都值得赞赏

答案1

否则,如果当前数据长度大于 50kb,则无论时间间隔有多大,都立即发送

无论如何,这种情况都会发生。 Nagle 算法的传输缓冲窗口不会大于底层数据包(即 MTU),因为这没有任何好处,并且在所有实际应用中这些缓冲窗口不会大于 9 kB。所以,我感觉你遇到的问题与你想象的不同。

如果最后发送的数据包与当前数据之间的时间间隔大于 100ms,则无论数据长度有多少,都立即发送

这种情况确实会发生——无论如何,除非你明确使用TCP_CORK,而且即便如此,延迟也会被限制在 200 毫秒。

我再次感觉到你遇到的问题与你想象的完全不同。

否则什么也不做,等待几毫秒做出下一个决定

请注意,对您的问题做出正确的“决定”需要应用程序级的数据流需求知识 - 因此,实际上,最简单且开销特别低的解决方案是相应地设计您的协议,并在传输小数据报之前积累它们您的应用程序,然后手动刷新(或使用TCP_NODELAY)。您还可以仔细阅读设置和取消设置,TCP_CORK让 Linux 内核为您进行存储。

这可能意味着您需要放弃 TCP 并采用 SCTP,或者在极端情况下,采用具有您自己的流量控制逻辑的 UDP – 考虑到您最初的声明,您似乎确实想要这样做:

这会错过另一端正确时间的数据。

这听起来像是您使用了对 TCP 错误的假设来错误设计了网络协议? TCP 不保证 RX 和 TX 之间的数据包顺序;仅每个 RX 和 TX单独地,数据顺序得到保证。

相关内容