![]() |
1
16
在应用程序层(使用Berkeley Socket样式的API),您只需观察时钟,并以您希望限制的速度读取或写入数据。 如果您平均只读取10 Kbps,但源发送的速度超过了10 Kbps,那么最终它与您之间的所有缓冲区都将填满。TCP/IP允许这样做,并且协议将安排发送方放慢速度(在应用层,您可能只需要知道在另一端,阻塞写入调用将阻塞,非阻塞写入将失败,异步写入将无法完成,直到您读取足够的数据来允许它)。 在应用程序层,您只能是近似值——您不能保证硬限制,例如“任何一秒钟内都不会超过10 kb通过网络中的一个给定点”。但是,如果你跟踪你收到的信息,从长远来看,你可以得到平均值。 |
![]() |
2
4
假设网络传输是基于TCP/IP的传输,则发送数据包是为了响应ACK/NACK数据包的另一种方式。 通过限制确认接收到传入数据包的数据包的速率,您将反过来降低发送新数据包的速率。 它可能有点不精确,所以它可能是最佳的监测下游速度和适应调整响应速度,直到它落在一个舒适的门槛内。(这种情况很快就会发生,不过,您会发送一秒的ACK剂量) |
![]() |
3
1
就像把游戏限制在一定数量的fps。
这样可以确保游戏刷新率最高为fps。 以同样的方式,drawscene可以是用于将字节泵入套接字流的函数。 |
![]() |
4
1
如果你从一个套接字读取数据,你就无法控制所用的带宽——你正在读取该套接字的操作系统缓冲区,你所说的任何内容都不会使写入套接字的人写更少的数据(当然,除非你为此制定了一个协议)。 缓慢读取所要做的就是填满缓冲区,并最终导致网络端的停顿——但您无法控制这种情况的发生方式或时间。 如果您真的想一次只读取这么多数据,可以这样做:
|
![]() |
5
0
wget似乎用限制利率选项来管理它。以下是手册页:
|
![]() |
6
0
正如其他人所说,操作系统内核正在管理流量,而您只是从内核内存中读取数据的副本。为了粗略地限制一个应用程序的速率,您需要延迟对数据的读取,并允许传入数据包在内核中进行缓冲,这最终会减慢对传入数据包的确认,并降低该套接字上的速率。 如果您想降低到机器的所有流量,您需要去调整传入TCP缓冲区的大小。在Linux中,您将通过更改/proc/sys/net/ipv4/tcp_rmem(读取内存缓冲区大小)和其他tcp_ux文件中的值来影响此更改。 |
![]() |
7
0
要补充布兰恩的答案: 如果您自愿限制接收端的读取速度,那么最终队列将在两端填满。然后,发送方将阻塞其send()调用,或者从send()调用返回,发送长度小于传递给send()调用的预期长度。 如果发送方没有准备好通过休眠和尝试重新发送不适合OS缓冲区的内容来处理这种情况,您将最终出现连接问题(发送方可能会将此检测为错误)或丢失数据(发送方可能在不知情的情况下丢弃不适合OS缓冲区的数据)。 |
![]() |
8
0
设置小型套接字发送和接收缓冲区,例如1K或2K,这样带宽*延迟积=缓冲区大小。您可能无法通过快速链接使其足够小。 |
![]() |
danial · 如何在多个字符串的每个位置找到最频繁的字符 2 年前 |
![]() |
Manny · 如何比较Perl中的字符串? 2 年前 |
![]() |
Diret · 获取范围内每个数字的子倍数的算法 2 年前 |
![]() |
Saif · 排序时python如何决定何时调用比较器? 2 年前 |