问题
I'm having troubles with UdpClient in C#. I am streaming audio over the internet between two clients.
On my microphone, with a sample rate of 16khz, I send UDP packets with audio with 6400 byte per packet. These never get through, except the last packet which is usally around 1200-3400 something since I close the recording. When I lower sample rate to 8khz, I send packets with 3200 byte payload. These always get through for some reason.
So basically anything above 3200 gets botched (havn't tested an exact number but...) why on earth is this? I was thinking perhaps the UdpClient internal buffer is too small or something? Since I stream audio packets gets sent frequently.
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());
}
}
I can't find any obvious fault. (The asyn object to the function is null btw, I do not need to use a stateobject , but that shouldn't be related to this)
I know UDP is not reliable, but considering every single 3200 sized packet get through and no 6400 size smells fishy to me, especially with max size is what, 64kb?
Any ideas?
回答1:
It is possible for packets exceeding the MTU (which I think is around 1500 bytes) to be discarded. For example, see this. It sounds like you may be running into some form of this. To allow it to work more reliably in different environments, it may be better to maximize the send to 1472 bytes per packet (to allow for packet overhead) and then reassemble them at the receiving end.
Or maybe just use TCP/IP. Even if some loss is acceptable, it can be rather complex to make a "simple" UDP solution work. I work on a product that supports communications for UDP and over TCP/IP, and (educated guess) the UDP implementation involves probably 10 times as much code and has much greater complexity. Of course, in our situation no data loss is acceptable, so that changes it some.
回答2:
You are guaranteed 576 bytes (548 for UDP payload) with IPv4, but you should look to keep under 1472 bytes (1444 UDP) at least for most users.
You can test what MTU size works using ping as described here,
http://help.expedient.net/broadband/mtu_ping_test.shtml
libjingle uses a safe default of 1280 bytes (1252 UDP/IPv4, 1232 UDP/IPv6) which matches the guaranteed minimum for IPv6,
http://code.google.com/p/libjingle/source/browse/branches/nextsnap/talk/session/tunnel/pseudotcpchannel.cc?spec=svn17&r=13
回答3:
Since 2014, this link may be the best answer for this question:
UdpClient class .NET Reference source.
private const int MaxUDPSize = 0x10000;
...
private byte[] m_Buffer = new byte[MaxUDPSize];
来源:https://stackoverflow.com/questions/4456243/udpclient-limited-buffersize