UdpClient - 限制缓冲区?

时间:2010-12-16 00:00:40

标签: c# networking udp udpclient

我在C#中遇到了UdpClient问题。我在两个客户之间通过互联网传输音频。

在我的麦克风上,采样率为16khz,我发送带有音频的UDP数据包,每个数据包6400字节。这些从来没有通过,除了最后的数据包,自从我关闭录音以来通常大约1200-3400的东西。 当我将采样率降低到8khz时,我发送3200字节有效载荷的数据包。由于某些原因,这些总是能够通过。

所以基本上3200以上的任何东西都会变得拙劣(没有测试确切的数字,但......)为什么这个呢?我想也许UdpClient内部缓冲区太小或什么?由于我流音频数据包被频繁发送。

RECEIVE:

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 btw,我不需要使用stateobject,但这不应该与此相关)

我知道UDP不可靠,但是考虑到每个3200大小的数据包都没有通过,没有6400大小对我来说有点腥味,尤其是最大大小是64kb?

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

可能会丢弃超过MTU(我认为大约为1500字节)的数据包。例如,see this。听起来你可能会碰到某种形式。为了使其在不同环境中更可靠地工作,最好将每个数据包的发送最大化为1472字节(以允许数据包开销),然后在接收端重新组装它们。

或者只是使用TCP / IP。即使可以接受一些损失,使“简单”UDP解决方案工作也相当复杂。我致力于支持UDP和TCP / IP通信的产品,并且(有教养的猜测)UDP实现可能涉及10倍的代码并且具有更高的复杂性。当然,在我们的情况下,没有数据丢失是可以接受的,所以改变一些。

答案 1 :(得分:0)

使用IPv4可以保证576个字节(UDP有效负载为548),但是对于大多数用户来说,你应该保持低于1472字节(1444 UDP)。

您可以使用ping测试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

答案 2 :(得分:0)

自2014年起,此链接可能是此问题的最佳答案:

UdpClient class .NET Reference source

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