Martin
Martin

Reputation: 1177

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

If one executes for example iperf -c 178.62.60.141 -fm -b 100m -u -t 30 -i 10, then after each 10 second interval, Iperf client prints out the amount of data it has transferred in 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

Same is true for TCP. Fact, that transferred data and bandwidth are printed out after the end of each interval and transferred data is sometimes bit more or less than the bandwidth specified with the "-b" flag, should mean that Iperf client actually somehow counts the sent data and doesn't just print the argument of "-b"(bandwidth) flag. Still, how does Iperf client count the amount of data it sends? It sure doesn't do this on low level because if I introduce 10% packet loss with tc, execute iperf -c 178.62.60.141 -fm -b 100m -u -t 30 -i 10 and then compare the packets Iperf client thought it sent(from Iperf client output) with the amount of packets actually were put to wire(from ip -s link show dev eth0 output), then Iperf client thought that it sent >250k datagrams while it actually did just bit over 230k. Exactly the same holds true if I police the traffic with tc Token Bucket Filter queuing discipline, i.e. according to Iperf client it has sent out traffic at 100Mbps while actual traffic rate was policed by policer.

If I try to analyze the source code of Iperf(http://ftp.de.debian.org/debian/pool/main/i/iperf/iperf_2.0.5.orig.tar.gz), then as I understand, client connection is coded in Client.cpp file in src directory using regular connect() system call? I guess the reporting is coded in Reporter.c file, but it gets too complicated for me to understand this.. Could someone please explain(with code samples) how does Iperf 2.x client detect the amount of traffic it has sent?

Upvotes: 0

Views: 802

Answers (2)

technosaurus
technosaurus

Reputation: 7802

You can track the return values of send(), write() or *printf() for the total amount written ... then every X amount of time print (current - last) and then set last to current.

In iperf this is done with calls to int iperf_tcp_send() (similar function for udp)

The return values for write(), send() and the *printf() functions is the number of characters written. If you use these functions without using the return value, it is prudent to prefix them with (void), but a lot of code I have seen ignores it, leading many programmers to presume that they are void functions.

Furthermore a call to write is not guaranteed to send all of the data, so the return value is actually useful to ensure that an entire buffer is fully written. To see a good example of this check out Rob Landley's Toybox implementation of writeall()

Upvotes: 1

Sam Varshavchik
Sam Varshavchik

Reputation: 118340

Before looking at the source code, this seemed fairly straightforward. The client should know how much stuff it sent. After all, it sent it. So, it must look at the system clock, obtain how long it took it to send a given amount of data, and figure out the rate.

And, now having looked at Reporter.c -- as expected, there are various gettimeofday() syscalls sprinkled in there, that grab the value of the system clock.

The amount of traffic this utility sent can't be such a big mystery. After all, it sent it, so it should know how much there was.

Upvotes: 3

Related Questions