【问题标题】:Limiting TCP sending rate限制 TCP 发送速率
【发布时间】:2016-08-09 05:17:22
【问题描述】:

TCP 流本身会增长,直到它们填满从srcdst 使用的链接的最大容量(如果所有这些链接都是空的)。

有没有简单的方法来限制它?我希望能够以最大 X mbps 速率发送 TCP 流。

我考虑过使用 socket.send() 函数每秒发送 X 个字节,然后在其余时间休眠。但是,如果链路拥塞并且速率降低,一旦链路再次不拥塞,它将需要恢复之前无法发送的内容,并且速率将会增加。

【问题讨论】:

  • 恢复将以更高的速度爆发,但长期的平均值仍应为您发送 socket.send() 的速度。
  • 有什么方法可以限制爆发吗?我正在使用一个超级拥塞的网络,所以我会一直遇到这些突发事件。
  • 你可以发送non-blocking(数据包的大小最大为MTU),但非阻塞模式让事情变得更加困难
  • @janbrohl 非阻塞与阻塞仅影响应用程序在本地套接字缓冲区填满时的行为方式,与线路上的速率无关。

标签: python linux sockets unix


【解决方案1】:

在 TCP 级别,您拥有的唯一控制是传递给 send() 的字节数以及调用它的频率。一旦 send() 将一些字节交给网络堆栈,它完全取决于网络堆栈它希望以多快(或多慢)发送它们。

鉴于上述情况,您可以通过监视已发送的字节数以及自开始发送以来经过了多长时间,并推迟对 send() 的后续调用(和/或发送次数传递给 send()) 的数据字节,以防止平均速率高于目标速率。

如果您想要比这更精细的控制,您需要使用 UDP 而不是 TCP。使用 UDP,您可以直接控制每个数据包的发送时间。 (而对于 TCP,网络堆栈决定何时发送每个数据包、数据包中的内容、何时重新发送丢弃的数据包等)

【讨论】:

  • 使用 UDP 我已经这样做了。对于我必须做的事情,我需要生成两种类型的流,并且我想以与 UDP 相同的方式限制 TCP。
  • AFAIK 限制你对 send() 的调用是你所能做的,除了破解 TCP 堆栈或编写你自己的 TCP 层。
  • 我想可能有帮助的一件事是将 setsockopt(SO_SNDBUF, ...) 调用到您可以逃脱的最小值,以便 TCP 堆栈在它用于您的套接字的传出 TCP 缓冲区。这样,任何重发“突发”都将保持尽可能小,即使只是因为 TCP 堆栈不会保存太多要重发的字节。
  • 如果我限制那个缓冲区,我会丢包吗?或者当缓冲区中没有更多空间时(例如拥塞时),socket.send() 会阻止我
  • 无论做什么都会丢包;这就是网络的本质。您不会有数据丢失,因为 TCP 层会将传出的数据保存在内存中,并根据需要多次重新传输,直到最终到达远程对等方。 (例外情况是,如果事情变得如此糟糕以至于 TCP 层最终放弃并中断 TCP 连接;此时任何未决的传出字节都将被简单地丢弃)(回答您的问题:是的,假设它是一个阻塞套接字,发送() 将在缓冲区满时阻塞)
猜你喜欢
  • 2020-03-25
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多