2010-04-27 5 views
5

Я написал приложение C++ (работает в Linux), которое обслуживает поток RTP около 400 кбит/с. Для большинства пунктов назначения это работает нормально, но в некоторых местах происходит потеря пакетов. Кажется, что проблемные адресаты имеют более медленное соединение, но для потока, который я отправляю, он должен быть достаточно быстрым.Как отлаживать потерю пакетов?

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

Я уже проверен несколько вещей: - в ТСРйитре, я вижу, все пакеты RTP выходя на отправляющей машине - есть UDP отправить буфер на месте (я попробовал размеры между 64KB и 300KB) - RTP-пакеты в основном остаются ниже 1400 байт, чтобы избежать фрагментации

Что может сделать приложение-отправитель, чтобы свести к минимуму вероятность потери пакетов и что было бы лучшим способом отладить такую ​​ситуацию?

ответ

9

Не отправляйте пакеты в больших горячих кусках.

Потери пакетов обычно вызваны медленными маршрутизаторами с ограниченным размером буфера пакетов. Медленный маршрутизатор может обрабатывать 1 Мбит/с просто отлично, если у него есть время для отправки, скажем, 10 пакетов, прежде чем получать еще 10, но если сторона отправителя со скоростью 100 Мбит/с отправит ей большой кусок из 50 пакетов, у него нет выбора, кроме как отказаться 40 из них.

Попробуйте разложить отправку, чтобы вы пишете только то, что необходимо писать за каждый период времени. Если вам приходится писать один пакет каждую пятую часть секунды, сделайте так, вместо того, чтобы писать 5 пакетов в секунду.

-2

Это может быть не тот ответ, который вы хотите, но если у меня были проблемы с потерей пакетов, я бы попытался переключить свое приложение на использование TCP и больше всего беспокоился о потере пакетов, исходящих из моего ума.

+0

Большая часть точки RTP заключается в использовании семантики UDP; в частности, позволяя потерять пакеты без остановки остальной части потока. – jesup

+0

Упс! Мне плохо, что я не знаю RTP. Я сейчас почитаю об этом. Спасибо за головы! –

1

Вам следует попытаться уменьшить скорость отправки пакетов. Медленное соединение может означать всевозможные вещи, и попытка отправить его пакеты (небольшие или большие) с высокой скоростью не поможет.

5

netstat имеет несколько полезных вариантов для отладки ситуации.

Первый из них является NetStat -su (дамп статистики UDP):

[email protected]:/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 процесса:

[email protected]:/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 интересующего вас соединения. Если значения высоки и не падают до нуля, процесс не может обрабатывать нагрузку.

Эти команды можно использовать для отправки и получения принимающей машины.

Также вы можете использовать ССО, который сочетает в себе трассировку и пинг - это пингует каждый хмель маршрут. Это может обнаружить медленный прыжок в вашем маршруте. Запустите его на других машинах, чтобы проверить подключение ко второму.

+1

Некоторые полезные советы здесь, но я не уверен, что это поможет ему. Фактическая потеря пакетов, вероятно, происходит на маршрутизаторе ISP, где он не может видеть статистику. –

+0

Действительно, я не вижу потери пакетов с netstat на отправляющей машине. К сожалению, путь к месту назначения связан с большим количеством сетевого оборудования, к которому я не могу получить доступ напрямую. –

+0

netstat вряд ли покажет что-нибудь полезное в этом случае. – Roddy

4

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

Очевидные вещи, чтобы сделать:

  • а: уменьшить общую скорость передачи данных
  • б: Снизить скорость передачи данных «пик», путем отправки небольших пакетов чаще , а не один огромный кусок каждые несколько секунд. т.е. УМЕНЬШИТЕ ваш UDP-адрес буфер - возможно, даже до 1400 байтов.
  • c: Посмотрите, можете ли вы переключиться на вариант протокола RTP TCP .

Если все остальное не работает, WireShark - твой друг. Это даст вам реальную картину того, сколько данных - и когда отправляется ваше приложение.

+0

Не слишком ли маленький буфер UDP-отправки означает, что пакеты автоматически теряются на отправляющей машине, как только происходит малейшая задержка? –

+0

@Gene - это маловероятно. Хотя UDP не гарантирует получение пакетов, он, безусловно, должен гарантировать, что пакет «отправлен» в той или иной форме. И если он не был отправлен, netstat покажет вам это, я думаю. [Когда вы говорите «UDP Buffer», что-то, что вы имеете в виду? Я думал, что UDP обычно не буферизирован ...?] – Roddy

+0

Каждый сокет (и это также относится к сокетам UDP) имеет буфер отправки, в котором данные хранятся до тех пор, пока сетевой стек не отправит его. Приложение может влиять на размер этого буфера с помощью setsockopt (SO_SNDBUF). Когда буфер заполнен, блок отправки TCP-пакетов и UDP отбрасывается. –

Смежные вопросы