Iperf2.x客户端如何检测其发送的流量

How does Iperf 2.x client detect the amount of traffic it has sent?

本文关键字:流量 检测 客户端 何检测 Iperf2      更新时间:2023-10-16

例如,如果执行iperf -c 178.62.60.141 -fm -b 100m -u -t 30 -i 10,则在每10秒的间隔后,Iperf客户端会打印出其传输的数据量(MB):

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的速度发送流量,而实际流量速率由policer来管理,情况也是如此。

如果我试图分析Iperf的源代码(http://ftp.de.debian.org/debian/pool/main/i/iperf/iperf_2.0.5.orig.tar.gz),那么据我所知,客户端连接是使用常规connect()系统调用在src目录中的client.cpp文件中编码的吗?我想报告是在Reporter.c文件中编码的,但它太复杂了,我无法理解。。有人能解释一下(用代码示例)Iperf2.x客户端是如何检测它发送的流量的吗?

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

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

这个实用程序发送的流量不会是一个很大的谜。毕竟,它发送了它,所以它应该知道有多少。

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

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

write(), send() and the *printf()函数的返回值是写入的字符数。如果在不使用返回值的情况下使用这些函数,那么明智的做法是在它们前面加上(void),但我看到的很多代码都忽略了这一点,导致许多程序员认为它们是void函数。

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