Как клиент Iperf 2.x определяет количество отправленного трафика?

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 подсчитывает количество отправленных данных? Конечно, это не так на низком уровне, потому что если я iperf -c 178.62.60.141 -fm -b 100m -u -t 30 -i 10 10% -ную потерю пакетов с помощью tc, выполните iperf -c 178.62.60.141 -fm -b 100m -u -t 30 -i 10 а затем сравните пакеты Iperf-клиент считал, что он отправил (с выхода клиента Iperf) количество пакетов, которые действительно были помещены в провод (из ip -s link show dev eth0 output), тогда клиент Iperf считал, что он отправил> 250 тыс. датаграмм, пока он действительно просто бит более 230 тыс. Точно так же сохраняется, если я контролирую трафик с помощью tc Token Bucket Filter, в соответствии с клиентом Iperf, он отправил трафик со скоростью 100 Мбит/с, в то время как фактическая скорость трафика была проверена полицейским.

Если я попытаюсь проанализировать исходный код Iperf (http://ftp.de.debian.org/debian/pool/main/i/iperf/iperf_2.0.5.orig.tar.gz), то, как я понимаю, клиент соединение закодировано в файле Client.cpp в каталоге src, используя обычный системный вызов connect()? Я думаю, что отчет кодируется в файле Reporter.c, но для меня это становится слишком сложным, чтобы понять это. Может ли кто-нибудь объяснить (с примерами кода), как клиент Iperf 2.x обнаруживает количество отправленного трафика?

Теги:
iperf

2 ответа

3
Лучший ответ

Прежде чем смотреть на исходный код, это выглядело довольно просто. Клиент должен знать, сколько материала он отправил. В конце концов, он отправил его. Таким образом, он должен смотреть на системные часы, получать, сколько времени потребовалось для отправки определенного количества данных, и выяснить скорость.

И теперь, посмотрев на Reporter.c - как и ожидалось, в нем посыпаются различные системные вызовы gettimeofday(), которые захватывают значение системных часов.

Объем трафика, отправляемого этой утилитой, не может быть такой большой загадкой. В конце концов, он отправил его, поэтому он должен знать, сколько было.

  • 0
    Я также заметил эти функции gettimeofday() в файлах Reporter.c и Client.cpp , но я не понял, где именно происходит синхронизация. Может быть, это только я, но сам код также выглядит немного запутанным. Я также ожидал бы, что отправка UDP-дейтаграмм выполняется с помощью функции write() а измерение полосы пропускания выполняется с помощью вызова gettimeofday() до и после отправки данных в сокет, но я был бы признателен за соответствующие фрагменты кода из исходного кода Iperf. ,
1

Вы можете отслеживать возвращаемые значения send(), write() or *printf() для общей суммы, записанной... тогда каждый X-период времени печатает (текущий - последний), а затем устанавливается последним на текущий.

В iperf это делается с вызовами int iperf_tcp_send() (аналогичная функция для udp)

Возвращаемые значения для функций write(), send() and the *printf() - это количество написанных символов. Если вы используете эти функции без использования возвращаемого значения, целесообразно префикс их (void), но многие из кода, которые я видел, игнорируют его, что приводит многих программистов к предположению, что они являются недействительными.

Кроме того, вызов на запись не гарантирует отправку всех данных, поэтому возвращаемое значение действительно полезно для обеспечения полного написания всего буфера. Чтобы увидеть хороший пример этой проверки Rob Landley Toybox, реализация writeall()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню