2010-12-16 264 views
5

J'ai des problèmes avec UdpClient en C#. Je diffuse de l'audio sur Internet entre deux clients.UdpClient - buffersize limité?

Sur mon micro, avec une fréquence d'échantillonnage de 16khz, j'envoie des paquets UDP avec de l'audio avec 6400 octets par paquet. Ceux-ci ne passent jamais, sauf le dernier paquet qui est habituellement autour de 1200-3400 quelque chose depuis que je ferme l'enregistrement. Lorsque je réduis la fréquence d'échantillonnage à 8 kHz, j'envoie des paquets avec une charge utile de 3200 octets. Ceux-ci passent toujours pour une raison quelconque.

Donc, fondamentalement, tout ce qui est au-dessus de 3200 est bousillé (n'a pas testé un nombre exact mais ...) pourquoi diable est-ce? Je pensais peut-être que le tampon interne UdpClient est trop petit ou quelque chose? Depuis que je stream flux audio est envoyé fréquemment.

RECEVOIR:

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()); 
     } 

    } 

Je ne peux trouver aucune faute évidente. (L'objet asyn à la fonction est null btw, je n'ai pas besoin d'utiliser un stateobject, mais cela ne devrait pas être lié à cela)

Je sais que le protocole UDP n'est pas fiable, mais étant donné que chaque paquet de taille 3200 passe à travers et pas 6400 odeurs de taille de poisson pour moi, surtout avec la taille maximale est ce que 64kb?

Des idées?

Répondre

2

Il est possible que des paquets dépassant le MTU (qui, je pense est d'environ 1500 octets) soient rejetés. Par exemple, see this. On dirait que vous courez peut-être sous une forme ou une autre. Pour lui permettre de fonctionner de manière plus fiable dans différents environnements, il peut être préférable de maximiser l'envoi à 1472 octets par paquet (pour permettre la surcharge des paquets) et de les réassembler ensuite à la réception.

Ou peut-être simplement utiliser TCP/IP. Même si une perte est acceptable, il peut être assez complexe de faire fonctionner une solution UDP «simple». Je travaille sur un produit qui prend en charge les communications pour UDP et sur TCP/IP, et (supposition éclairée) l'implémentation UDP implique probablement 10 fois plus de code et est beaucoup plus complexe. Bien sûr, dans notre situation, aucune perte de données n'est acceptable, ce qui en modifie la valeur.

+0

Avec le fait que ce trafic se passe sur Internet, cela ressemble à ce qui se passe. –

+0

Pour développer cela, les paquets IP plus grands que le MTU seront fragmentés. Si tous les fragments arrivent à la destination, ils seront réassemblés dans le paquet IP d'origine (contenant le datagramme UDP d'origine) par la couche IP.S'ils n'arrivent pas tous, il n'y a pas de mécanisme dans UDP pour demander une retransmission, donc le datagramme entier sera perdu. – EJP

+0

Merci, c'est clair maintenant! – KaiserJohaan

0

Vous avez une garantie de 576 octets (548 pour la charge utile UDP) avec IPv4, mais vous devriez garder moins de 1472 octets (1444 UDP) au moins pour la plupart des utilisateurs.

Vous pouvez tester la taille MTU fonctionne en utilisant ping comme décrit ici,

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

libjingle utilise un défaut sûr de 1280 octets (1252 UDP/IPv4, 1232 UDP/IPv6) qui correspond au minimum garanti pour IPv6,

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