【问题标题】:How do you throttle the bandwidth of a socket connection in C?如何在 C 中限制套接字连接的带宽?
【发布时间】:2010-09-19 03:26:34
【问题描述】:

我正在使用 BSD 套接字编写客户端-服务器应用程序。它需要在后台运行,不断传输数据,但不能占用正常使用的网络接口带宽。根据接口的速度,我需要将此连接限制到某个最大传输速率。

以编程方式实现这一目标的最佳方法是什么?

【问题讨论】:

  • 将套接字接收缓冲区大小设置为所需的带宽延迟乘积。

标签: c++ c sockets network-programming


【解决方案1】:

在每次传输后持续休眠 1 秒的问题是您的网络性能会不稳定。

令 BandwidthMaxThreshold 为所需的带宽阈值。

令 TransferRate 为连接的当前传输速率。

那么……

如果您检测到您的 TransferRate > BandwidthMaxThreshold,那么您执行 SleepTime = 1 + SleepTime * 1.02(将睡眠时间增加 2%)

在每次网络操作之前​​或之后做一个 睡眠(睡眠时间)

如果您检测到您的 TransferRate 比您的 BandwidthMaxThreshold 低很多,您可以减少您的 SleepTime。或者,您可以始终随着时间的推移衰减/减少您的睡眠时间。最终,您的 SleepTime 将再次达到 0。

除了增加 2% 之外,您还可以将 TransferRate - BandwidthMaxThreshold 之间的差值线性增加一个较大的量。

这个解决方案很好,因为如果用户的网络已经没有你想要的那么高,你将没有睡眠。

【讨论】:

  • @Brian:为什么需要'1 +'? SleepTime = 1.02 * SleepTime 本身不会增加 2% 的值吗?
  • 我刚刚添加了它,这样如果您的 SleepTime 变为 0,它将能够再次增长。也使它在必须增长时总是增长至少 1。
  • 如果协议使用确认,那么在收到响应之前的延迟也可用于提供端到端的管道延迟并建议传输消息的速率。这将提供一种自适应解决方案,允许在多个安装中进行自我调整。
【解决方案2】:

最好的方法是使用token bucket

只有当你有足够的令牌来填充一个数据包时才发送(1460 字节是一个很好的数量),或者如果你是接收方,只有当你有足够的令牌时才从套接字读取;一些简单的数学运算会告诉您在获得足够的令牌之前必须等待多长时间,这样您就可以睡这么长的时间(小心计算您获得了多少令牌实际上睡眠,因为大多数操作系统可以让您的进程睡眠的时间比您要求的时间长)。

要控制爆发的大小,请限制您可以拥有的最大代币数量;相当数量可能是一秒钟的代币。

【讨论】:

    【解决方案3】:

    我与trickle 相处得很好。这很酷,因为它可以在不修改的情况下限制任意用户空间应用程序。它通过预加载自己的发送/接收包装函数来为您计算带宽。

    我发现的最大缺点是很难协调多个要共享有限带宽的应用程序。 “涓涓细流”有帮助,但我发现它很复杂。

    2017 年更新:看起来涓涓细流已移至 https://github.com/mariusae/trickle

    【讨论】:

      猜你喜欢
      • 2021-05-18
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2012-05-24
      • 2013-04-17
      • 2010-10-27
      • 2014-06-02
      相关资源
      最近更新 更多