Iperf 2.x客户端如何检测它发送的流量?

时间:2014-09-01 11:55:44

标签: c++ c linux iperf

如果执行例如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>

2 个答案:

答案 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()