我正在使用 BSD 套接字编写客户端-服务器应用程序。它需要在后台运行,不断传输数据,但不能占用正常使用的网络接口带宽。根据接口的速度,我需要将此连接限制到某个最大传输速率。
以编程方式实现这一目标的最佳方法是什么?
我正在使用 BSD 套接字编写客户端-服务器应用程序。它需要在后台运行,不断传输数据,但不能占用正常使用的网络接口带宽。根据接口的速度,我需要将此连接限制到某个最大传输速率。
以编程方式实现这一目标的最佳方法是什么?
每次传输后持续休眠 1 秒的问题是您的网络性能会不稳定。
令 BandwidthMaxThreshold 为所需的带宽阈值。
令 TransferRate 为连接的当前传输速率。
然后...
如果您检测到您的 TransferRate > BandwidthMaxThreshold,那么您执行 SleepTime = 1 + SleepTime * 1.02(将睡眠时间增加 2%)
在每次网络操作之前或之后做一个 Sleep(SleepTime)
如果您检测到您的 TransferRate 比您的 BandwidthMaxThreshold 低很多,您可以减少您的 SleepTime。或者,您可以始终随着时间的推移衰减/减少您的睡眠时间。最终,您的 SleepTime 将再次达到 0。
除了增加 2% 之外,您还可以线性增加 TransferRate - BandwidthMaxThreshold 之间的差值。
这个解决方案很好,因为如果用户的网络已经没有你想要的那么高,你将没有睡眠。
最好的方法是使用令牌桶。
仅当您有足够的令牌来填充数据包时才发送(1460 字节将是一个很好的数量),或者如果您是接收方,则仅当您有足够的令牌时才从套接字读取;一些简单的数学运算会告诉您在获得足够的令牌之前必须等待多长时间,这样您就可以睡这么长的时间(小心计算您实际睡眠的时间获得了多少令牌,因为大多数操作系统都可以让你的进程睡眠的时间比你要求的要长)。
要控制爆发的大小,请限制您可以拥有的最大代币数量;很多可能是一秒钟的代币。
我在涓涓细流方面运气不错。这很酷,因为它可以在不修改的情况下限制任意用户空间应用程序。它通过预加载自己的发送/接收包装函数来工作,这些函数会为您计算带宽。
我发现的最大缺点是很难协调您想要共享有限带宽的多个应用程序。“涓涓细流”有帮助,但我发现它很复杂。
2017 年更新:看起来涓涓细流已移至https://github.com/mariusae/trickle