Я записал приложение C++ (работающий на Linux), который служит потоку RTP приблизительно 400 Кбит/с. Большинству мест назначения это хорошо работает, но некоторые места назначения expericence потеря пакетов. У проблематичных мест назначения, кажется, есть медленнее общее соединение, но это должно быть много достаточно быстро для потока, который я отправляю.
Так как эти места назначения могут получить подобные потоки RTP для других приложений без потери пакетов, мое приложение могло бы быть виновным.
Я уже проверил несколько вещей: - в tcpdump я вижу, что все пакеты RTP выходят на передающей машине - существует UDP, отправляют буфер на месте (я попробовал размеры между 64 КБ и 300 КБ) - пакеты RTP главным образом остаются ниже 1 400 байтов для предотвращения фрагментации
Что заявление отправки может сделать для уменьшения возможности потери пакетов и каков был бы лучший способ отладить такую ситуацию?
Не отправлять пакеты большими пакетными порциями.
Потеря пакетов обычно вызвана медленными маршрутизаторами с ограниченным размером буфера пакетов. Медленный маршрутизатор может нормально обрабатывать 1 Мбит / с, если у него есть время отправить, скажем, 10 пакетов, прежде чем получить еще 10, но если сторона отправителя 100 Мбит / с отправляет ему большой кусок из 50 пакетов, у нее нет другого выбора, кроме как отбросить 40 из них.
Попробуйте распределить рассылку так, чтобы вы писали только то, что необходимо написать в каждый период времени. Если вам нужно записывать один пакет каждую пятую секунды, сделайте это так, вместо того, чтобы записывать 5 пакетов в секунду.
Возможно, это не тот ответ, который вам нужен, но если бы у меня были проблемы с потерей пакетов, я бы попытался переключить свое приложение на использование TCP, и меня больше всего беспокоит о потере пакетов я забыл.
netstat имеет несколько полезных опций для отладки ситуации.
Первый - netstat -su (дамп статистики UDP):
dima@linux-z8mw:/media> netstat -su
IcmpMsg:
InType3: 679
InType4: 20
InType11: 548
OutType3: 100
Udp:
12945 packets received
88 packets to unknown port received.
0 packet receive errors
13139 packets sent
RcvbufErrors: 0
SndbufErrors: 0
UdpLite:
InDatagrams: 0
NoPorts: 0
InErrors: 0
OutDatagrams: 0
RcvbufErrors: 0
SndbufErrors: 0
IpExt:
InNoRoutes: 0
InTruncatedPkts: 0
InMcastPkts: 3877
OutMcastPkts: 3881
InBcastPkts: 0
OutBcastPkts: 0
InOctets: 7172779304
OutOctets: 785498393
InMcastOctets: 525749
OutMcastOctets: 525909
InBcastOctets: 0
OutBcastOctets: 0
Обратите внимание на «RcvbufErrors» и «SndbufErrors»
Дополнительная опция - отслеживать получение и отправку буферов UDP процесса:
dima@linux-z8mw:/media> netstat -ua
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
udp 0 0 *:bootpc *:*
udp 0 0 *:40134 *:*
udp 0 0 *:737 *:*
udp 0 0 *:mdns *:*
Здесь вам нужно посмотрите столбцы Recv-Q и Send-Q интересующего вас соединения. Если значения высокие и не опускаются до нуля, значит процесс не может справиться с нагрузкой.
Вы можете использовать эти команды на отправляющем и на принимающем аппарате.
Также вы можете использовать mtr , который объединяет traceroute и ping - он проверяет каждый переход в маршруте. Это может обнаружить медленный переход на вашем маршруте. Запустите его на других машинах, чтобы проверить подключение ко второму.
RTP обычно использует UDP , который по своей сути является потерянным. Пакеты могут быть потеряны где угодно между отправителем и получателем, поэтому локальная отладка не покажет вам ничего полезного.
Очевидные действия:
Если ничего не помогает, WireShark - ваш друг. Это даст вам истинное представление о том, сколько данных и когда отправляется вашим приложением.
Попробуйте уменьшить скорость отправки пакетов. Медленное соединение может означать разные вещи, и попытки отправить ему пакеты (маленькие или большие) с высокой скоростью не помогут.