0

例如,如果执行iperf -c 178.62.60.141 -fm -b 100m -u -t 30 -i 10,则在每 10 秒间隔后,Iperf 客户端会打印出它已传输的数据量(以兆字节为单位):

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 客户端如何计算它发送的数据量?它肯定不会在低级别执行此操作,因为如果我引入 10% 的数据包丢失tc,执行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 客户端如何检测它发送的流量吗?

4

2 回答 2

3

在查看源代码之前,这似乎相当简单。客户应该知道它发送了多少东西。毕竟是送的。因此,它必须查看系统时钟,获取发送给定数量数据所用的时间,并计算出速率。

而且,现在查看了 Reporter.c —— 正如预期的那样,那里散布着各种 gettimeofday() 系统调用,它们获取系统时钟的值。

这个实用程序发送的流量不可能是一个很大的谜。毕竟是送过来的,应该知道有多少。

于 2014-09-03T12:39:00.833 回答
1

您可以跟踪总写入量的返回值send(), write() or *printf()...然后每 X 时间打印一次(当前 - 最后一次),然后将最后一次设置为当前。

在 iperf 中,这是通过调用int iperf_tcp_send()(udp 的类似函数)来完成的

函数的返回值write(), send() and the *printf()是写入的字符数。如果你使用这些函数而不使用返回值,谨慎的做法是在它们前面加上 (void),但是我看到的很多代码都忽略了它,导致许多程序员假定它们是 void 函数。

此外,调用 write 并不能保证发送所有数据,因此返回值实际上有助于确保整个缓冲区被完全写入。要查看一个很好的示例,请查看Rob Landley 的 writeall() 的 Toybox 实现

于 2014-09-05T03:18:38.800 回答