14

If I use iperf with -y C and -r arguments to test bidirectional transfer and export it as a CSV.

I get some output but the problem is that I don't know what the column names are. For example it shows three rows of data but I don't know which corresponds to send and which to receive.

The other columns I can guess, but I would rather be sure.

I can't find this documented anywhere!

5 Answers 5

12
+50

The fields are

timestamp,source_address,source_port,destination_address,destination_port,interval,transferred_bytes,bits_per_second

I deduced this by looking at

$ iperf -c localhost -r
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
------------------------------------------------------------
Client connecting to localhost, TCP port 5001
TCP window size:  648 KByte (default)
------------------------------------------------------------
[  5] local 127.0.0.1 port 54401 connected with 127.0.0.1 port 5001
[  4] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 54401
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0-10.0 sec  50.3 GBytes  43.2 Gbits/sec
[  4]  0.0-10.0 sec  50.3 GBytes  43.2 Gbits/sec

$ iperf -c localhost -r -y C
20140114124826,127.0.0.1,54402,127.0.0.1,5001,5,0.0-10.0,52551090176,42041052917
20140114124826,127.0.0.1,5001,127.0.0.1,54402,4,0.0-10.0,52551090200,41999020136

EDIT: You can find the relevant source code here:

// TCP Reporting
printf( reportCSV_bw_format,
timestamp,
(stats->reserved_delay == NULL ? ",,," : stats->reserved_delay),
stats->transferID,
stats->startTime,
stats->endTime,
stats->TotalLen,
speed);
} else {
// UDP Reporting
printf( reportCSV_bw_jitter_loss_format,
timestamp,
(stats->reserved_delay == NULL ? ",,," : stats->reserved_delay),
stats->transferID,
stats->startTime,
stats->endTime,
stats->TotalLen,
speed,
stats->jitter*1000.0,
stats->cntError,
stats->cntDatagrams,
(100.0 * stats->cntError) / stats->cntDatagrams, stats->cntOutofOrder );
} 
5

The accepted answer skips one odd field: the one that comes after the source and destination IP+port pairs:

timestamp,
source_address,
source_port,
destination_address,
destination_port,
XXX,                  <---- this one
interval,
transferred_bytes,
bits_per_second

The code in the accepted answer says this comes from the transferID variable. Some of the other answers here seem to argue that it represents a connection identifier or connection direction. However, a quick dive through the code indicates that transferID comes from a global variable named groupID. It is initialized to zero:

// Global ID that we increment to be used 
// as identifier for SUM reports
int groupID = 0;

However, a quick grep through the code seems to indicate that it is incremented and decremented a lot, very confusingly. There don't seem to be any defined constants that say what it means. Manual testing (iperf version 2.0.9 (9 Sept 2016) pthreads) shows the number being reused between connections. So I guess the moral of the story is... ignore that number? Or use iperf3.

3

date and time, source IP, source port, destination IP, destination port, iperf process number, time interval, amount of data transferred (bytes), bandwidth (bits per second), jitter (milliseconds), number of lost datagrams, total number of datagrams sent, percentage loss, number of datagrams received out of order

I got the above information from:

http://www.jb.man.ac.uk/~jcullen/code/python/iperf_tests.py

1

Look at the 6th field assuming "," (comma) being a field separator. Then look at these lines here:

Server listening on TCP port 5001
------------------------------------------------------------
Client connecting to localhost, TCP port 5001

[ 5] local 127.0.0.1 port 54401 connected with 127.0.0.1 port 5001 [ 4] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 54401 [ ID] Interval Transfer Bandwidth [ 5] 0.0-10.0 sec 50.3 GBytes 43.2 Gbits/sec [ 4] 0.0-10.0 sec 50.3 GBytes 43.2 Gbits/sec

"5" indicates client -> server connection, then "4" indicates "server -> client" connection (look at the source/destination ports to tell, in this particular example given by "sciurus".

0

Here is a simple demo using the CSV values and running in a loop checking for a given bps being met.

I also found there is an extra field present from the answers above which is 3/4/5 in value. 4 and 5 seem to be direction. 3 I'm not sure what it means. Anyway, in case this helps:

#!/usr/bin/python

import sys
import subprocess
from subprocess import Popen

def runProcess(exe):
    p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while(True):
      retcode = p.poll() #returns None while subprocess is running
      line = p.stdout.readline()
      yield line
      if(retcode is not None):
        break

#
# do an iperf to a peer and check the bps calculated is at least
# what we asked for
#
def peer_run_until_target_bps_not_met (peer, sample_period, target_bps):

    debug = 0
    target_kbps = target_bps / 1024.0
    target_mbps = target_bps / (1024.0 * 1024.0)
    cmd = "iperf -c %s -t %d -i %d -y C" % (peer, sample_period, sample_period)

    while (True):
        bps=0
        for line in runProcess(cmd.split()):
            if line == "":
                break

            if (debug):
                print "timestamp           %s" % line.split(',')[0]
                print "source_address      %s" % line.split(',')[1]
                print "source_port         %s" % line.split(',')[2]
                print "destination_address %s" % line.split(',')[3]
                print "destination_port    %s" % line.split(',')[4]

                #
                # "3" ???
                # "5" indicates client -> server connection,
                # "4" indicates "server -> client"
                #
                print "direction           %s" % line.split(',')[5]

                print "interval            %s" % line.split(',')[6]
                print "transferred_bytes   %s" % line.split(',')[7]
                print "bits_per_second     %s" % line.split(',')[8]

            transferred_bytes = float(line.split(',')[7])
            bps = (transferred_bytes * 8) / float(sample_period)

        kbps = bps / 1024.0
        mbps = bps / (1024.0 * 1024.0)
        print "OK: %12.2f bps / %10.2f Kbps / %10.2f Mbps (target %-10.2f Mbps)" % (bps, kbps, mbps, target_mbps)

        if (bps < target_bps):
            print "FAILED: need %.2f bps / %.2fKbps / %.2f Mbps" % \
        (target_bps, target_kbps, target_mbps)
            return

peer_run_until_target_bps_not_met("10.2.0.0", 5, 0.2 * 1024 * 1024) # 10 Mbps

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .