UdpClient - ограниченный размер буфера? - PullRequest
5 голосов
/ 16 декабря 2010

У меня проблемы с UdpClient в C #.Я передаю аудио через Интернет между двумя клиентами.

На моем микрофоне с частотой дискретизации 16 кГц я отправляю UDP-пакеты со звуком с 6400 байт на пакет.Они никогда не проходят, кроме последнего пакета, который обычно составляет около 1200-3400 с тех пор, как я закрываю запись.Когда я понижаю частоту дискретизации до 8 кГц, я отправляю пакеты с полезной нагрузкой 3200 байт.Они всегда проходят по какой-то причине.

Так что в целом все, что выше 3200, испортилось (не проверил точное число, но ...), с какой стати это?Я думал, может быть, внутренний буфер UdpClient слишком мал или что-то?Поскольку я передаю аудиопакеты, они часто отправляются.

ПОЛУЧИТЬ:

private void audioReceive(IAsyncResult asyn)
    {
        try
        {
            byte[] temp = audioSock.EndReceive(asyn, ref this.serverEP);
            this.waveProvider.AddSamples(temp, 0, temp.Length);

            this.textbox_display.Text = this.textbox_display.Text + " got bytes: " + temp.Length;
            audioSock.BeginReceive(new AsyncCallback(audioReceive), null);

        }
        catch (Exception ez)
        {
            MessageBox.Show("audioReceive: " + this.textbox_nick.Text + "        " +ez.ToString());
        }

    }

Я не могу найти очевидную ошибку.(Между прочим, асинхронный объект для функции равен null, мне не нужно использовать объект состояния, но это не должно быть связано с этим)

Я знаю, что UDP не надежен, но рассматривает каждый пакет размером 3200пройти и размер 6400 не пахнет для меня подозрительно, особенно с максимальным размером 64кб?

Есть идеи?

Ответы [ 3 ]

2 голосов
/ 16 декабря 2010

Возможно отбрасывание пакетов, превышающих MTU (я думаю, около 1500 байт).Например, см. Это .Похоже, вы можете столкнуться с какой-то формой этого.Чтобы позволить ему работать более надежно в разных средах, может быть лучше максимизировать отправку до 1472 байта на пакет (чтобы учесть издержки пакета), а затем повторно собрать их на принимающей стороне.

Или, может быть, просто использовать TCP / IP.Даже если некоторая потеря приемлема, сделать «простое» решение UDP может быть довольно сложно.Я работаю над продуктом, который поддерживает связь по протоколу UDP и по TCP / IP, и (догадывающееся предположение) реализация UDP, вероятно, содержит в 10 раз больше кода и имеет гораздо большую сложность.Конечно, в нашей ситуации потеря данных неприемлема, поэтому она немного меняется.

0 голосов
/ 29 марта 2015

С 2014 года эта ссылка может быть лучшим ответом на этот вопрос:

Класс UdpClient. Справочный источник .

private const int MaxUDPSize = 0x10000;  
...
private byte[] m_Buffer = new byte[MaxUDPSize];
0 голосов
/ 16 декабря 2010

Вам гарантировано 576 байтов (548 для полезной нагрузки UDP) с IPv4, но вы должны стремиться сохранить как минимум 1472 байта (1444 UDP) как минимум для большинства пользователей.

Вы можете проверить, какой размер MTU работает, используяПинг, как описано здесь,

http://help.expedient.net/broadband/mtu_ping_test.shtml

libjingle использует безопасное значение по умолчанию 1280 байтов (1252 UDP / IPv4, 1232 UDP / IPv6), что соответствуетгарантированный минимум для IPv6,

http://code.google.com/p/libjingle/source/browse/branches/nextsnap/talk/session/tunnel/pseudotcpchannel.cc?spec=svn17&r=13

...