UdpClient-ограниченный размер буфера?


У меня возникли проблемы с 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());
        }

    }

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

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

Есть идеи?

3 5

3 ответа:

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

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

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

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

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

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

UdpClient class .NET Reference source .

private const int MaxUDPSize = 0x10000;  
...
private byte[] m_Buffer = new byte[MaxUDPSize];