如果执行例如iperf -c 178.62.60.141 -fm -b 100m -u -t 30 -i 10
,则在每10秒间隔后,Iperf客户端打印出它以mebibytes传输的数据量:
root@vserver:~# iperf -c 178.62.60.141 -fm -b 100m -u -t 30 -i 10
WARNING: option -b implies udp testing
------------------------------------------------------------
Client connecting to 178.62.60.141, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size: 0.22 MByte (default)
------------------------------------------------------------
[ 3] local 146.185.187.148 port 37660 connected with 178.62.60.141 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 119 MBytes 100 Mbits/sec
[ 3] 10.0-20.0 sec 119 MBytes 100 Mbits/sec
[ 3] 20.0-30.0 sec 119 MBytes 100 Mbits/sec
[ 3] 0.0-30.0 sec 358 MBytes 100 Mbits/sec
[ 3] Sent 255661 datagrams
TCP也是如此。事实上,传输的数据和带宽在每个间隔结束后打印出,并且传输的数据有时比“-b”标志指定的带宽多或少,应该意味着Iperf客户端实际上以某种方式计算发送的数据,而不只是打印“-b”(带宽)标志的参数。怎么样呢
Iperf客户端计算它发送的数据量?它肯定不会在低级别上执行此操作,因为如果我使用tc
引入10%的数据包丢失,请执行iperf -c 178.62.60.141 -fm -b 100m -u -t 30 -i 10
然后将Iperf客户端认为它发送的数据包(来自Iperf客户端输出)与数据进行比较实际上数据包被放到线路上(来自ip -s link show dev eth0
输出),然后Iperf客户端认为它发送了> 250k数据报,而它实际上只有超过230k。如果我使用tc
令牌桶过滤器排队规则来监控流量,则完全相同,即根据Iperf客户端,它已经以100Mbps发送流量,而实际流量速率由监管者监管。
如果我尝试分析Iperf(http://ftp.de.debian.org/debian/pool/main/i/iperf/iperf_2.0.5.orig.tar.gz)的源代码,那么据我所知,客户端连接是使用常规connect()系统调用在src目录中的Client.cpp文件中编码的?我想报告是在Reporter.c文件中编码的,但是对我来说理解这个太复杂了。有人可以解释一下(带代码示例)Iperf 2.x客户端如何检测它发送的流量? / p>
答案 0 :(得分:3)
在查看源代码之前,这看起来相当简单。客户应该知道它发送了多少东西。毕竟,它发送了它。因此,它必须查看系统时钟,获取发送给定数量的数据所需的时间,并计算出速率。
而且,现在看了Reporter.c - 正如预期的那样,有各种各样的gettimeofday()系统调用,它们可以获取系统时钟的值。
这个实用程序发送的流量不是一个很大的谜。毕竟,它发送了它,所以应该知道它有多少。
答案 1 :(得分:1)
您可以跟踪send(), write() or *printf()
的总回写金额的返回值...然后每X个时间打印(当前 - 最后),然后将最后一个设置为当前。
在iperf中,这是通过调用int iperf_tcp_send()
完成的(udp的类似功能)
write(), send() and the *printf()
函数的返回值是写入的字符数。如果你在不使用返回值的情况下使用这些函数,那么使用(void)作为前缀是明智的,但是我看到的很多代码都忽略了它,导致许多程序员认为它们是无效函数。
此外,写入调用不能保证发送所有数据,因此返回值实际上对确保完整写入整个缓冲区非常有用。要查看此检查的一个很好的示例Rob Landley's Toybox implementation of writeall()