Groupe de multidiffusion UDP sur Windows Phone 8

OK, c’est celui que j’essaie de comprendre depuis quelques jours maintenant. Nous avons une application sur Windows Phone 7 où les téléphones rejoignent un groupe de multidiffusion, puis envoient et reçoivent des messages au groupe pour se parler. Remarque: il s’agit d’une communication entre téléphone et téléphone.

J’essaie maintenant de porter cette application sur Windows Phone 8 – en utilisant la fonctionnalité «Convertir en téléphone 8» de Visual Studio 2012 – jusqu’ici tout va bien. Jusqu’à ce que j’essaie de tester le téléphone pour téléphoner. Les combinés semblent rejoindre le groupe correctement, et ils envoient les datagrammes OK. Ils reçoivent même les messages qu’ils envoient au groupe – cependant, aucun combiné ne reçoit un message d’un autre combiné.

Voici l’exemple de code derrière ma page:

// Constructor public MainPage() { InitializeComponent(); } // The address of the multicast group to join. // Must be in the range from 224.0.0.0 to 239.255.255.255 private const ssortingng GROUP_ADDRESS = "224.0.1.1"; // The port over which to communicate to the multicast group private const int GROUP_PORT = 55562; // A client receiver for multicast traffic from any source UdpAnySourceMulticastClient _client = null; // Buffer for incoming data private byte[] _receiveBuffer; // Maximum size of a message in this communication private const int MAX_MESSAGE_SIZE = 512; private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) { _client = new UdpAnySourceMulticastClient(IPAddress.Parse(GROUP_ADDRESS), GROUP_PORT); _receiveBuffer = new byte[MAX_MESSAGE_SIZE]; _client.BeginJoinGroup( result => { _client.EndJoinGroup(result); _client.MulticastLoopback = true; Receive(); }, null); } private void SendRequest(ssortingng s) { if (ssortingng.IsNullOrWhiteSpace(s)) return; byte[] requestData = Encoding.UTF8.GetBytes(s); _client.BeginSendToGroup(requestData, 0, requestData.Length, result => { _client.EndSendToGroup(result); Receive(); }, null); } private void Receive() { Array.Clear(_receiveBuffer, 0, _receiveBuffer.Length); _client.BeginReceiveFromGroup(_receiveBuffer, 0, _receiveBuffer.Length, result => { IPEndPoint source; _client.EndReceiveFromGroup(result, out source); ssortingng dataReceived = Encoding.UTF8.GetSsortingng(_receiveBuffer, 0, _receiveBuffer.Length); ssortingng message = Ssortingng.Format("[{0}]: {1}", source.Address.ToSsortingng(), dataReceived); Log(message, false); Receive(); }, null); } private void Log(ssortingng message, bool isOutgoing) { if (ssortingng.IsNullOrWhiteSpace(message.Trim('\0'))) { return; } // Always make sure to do this on the UI thread. Deployment.Current.Dispatcher.BeginInvoke( () => { ssortingng direction = (isOutgoing) ? ">> " : "<< "; string timestamp = DateTime.Now.ToString("HH:mm:ss"); message = timestamp + direction + message; lbLog.Items.Add(message); // Make sure that the item we added is visible to the user. lbLog.ScrollIntoView(message); }); } private void btnSend_Click(object sender, RoutedEventArgs e) { // Don't send empty messages. if (!String.IsNullOrWhiteSpace(txtInput.Text)) { //Send(txtInput.Text); SendRequest(txtInput.Text); } } private void btnStart_Click(object sender, RoutedEventArgs e) { SendRequest("start now"); } 

Afin de tester simplement la stack UDP, j’ai téléchargé l’exemple de MSDN trouvé ici et je l’ai testé sur une paire de périphériques Windows Phone 7 et cela fonctionne comme prévu. Ensuite, j’ai converti à Windows Phone 8 et déployé sur mes combinés, là encore, les appareils semblent initier leur connexion, et l’utilisateur peut entrer son nom. Cependant, là encore, les appareils ne peuvent ni voir ni communiquer avec d’autres appareils.

Enfin, j’ai mis en œuvre un test de communication simple en utilisant la nouvelle implémentation de DatagramSocket, et encore une fois, je vois une initiation réussie, mais aucune communication entre les appareils.

Ceci est le même code derrière la page en utilisant l’implémentation du socket datagramme:

 // Constructor public MainPage() { InitializeComponent(); } // The address of the multicast group to join. // Must be in the range from 224.0.0.0 to 239.255.255.255 private const ssortingng GROUP_ADDRESS = "224.0.1.1"; // The port over which to communicate to the multicast group private const int GROUP_PORT = 55562; private DatagramSocket socket = null; private void Log(ssortingng message, bool isOutgoing) { if (ssortingng.IsNullOrWhiteSpace(message.Trim('\0'))) return; // Always make sure to do this on the UI thread. Deployment.Current.Dispatcher.BeginInvoke( () => { ssortingng direction = (isOutgoing) ? ">> " : "<< "; string timestamp = DateTime.Now.ToString("HH:mm:ss"); message = timestamp + direction + message; lbLog.Items.Add(message); // Make sure that the item we added is visible to the user. lbLog.ScrollIntoView(message); }); } private void btnSend_Click(object sender, RoutedEventArgs e) { // Don't send empty messages. if (!String.IsNullOrWhiteSpace(txtInput.Text)) { //Send(txtInput.Text); SendSocketRequest(txtInput.Text); } } private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) { socket = new DatagramSocket(); socket.MessageReceived += socket_MessageReceived; try { // Connect to the server (in our case the listener we created in previous step). await socket.BindServiceNameAsync(GROUP_PORT.ToString()); socket.JoinMulticastGroup(new Windows.Networking.HostName(GROUP_ADDRESS)); System.Diagnostics.Debug.WriteLine(socket.ToString()); } catch (Exception exception) { throw; } } private async void SendSocketRequest(string message) { // Create a DataWriter if we did not create one yet. Otherwise use one that is already cached. //DataWriter writer; var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(GROUP_ADDRESS), GROUP_PORT.ToString()); //writer = new DataWriter(socket.OutputStream); DataWriter writer = new DataWriter(stream); // Write first the length of the string as UINT32 value followed up by the string. Writing data to the writer will just store data in memory. // stream.WriteAsync( writer.WriteString(message); // Write the locally buffered data to the network. try { await writer.StoreAsync(); Log(message, true); System.Diagnostics.Debug.WriteLine(socket.ToString()); } catch (Exception exception) { throw; } finally { writer.Dispose(); } } void socket_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) { try { uint stringLength = args.GetDataReader().UnconsumedBufferLength; string msg = args.GetDataReader().ReadString(stringLength); Log(msg, false); } catch (Exception exception) { throw; } } 

Hier soir, j’ai ramené les combinés à la maison pour les tester sur mon réseau sans fil domestique, et voilà que je parviens à communiquer avec le périphérique.

Donc, pour résumer, mon code Windows Phone 7 hérité fonctionne bien sur mon réseau de travail. Le port vers Windows Phone 8 (pas de changement de code réel) n’envoie pas de communication inter-appareil. Ce code fonctionne sur mon réseau domestique. Le code s’exécute avec le débogueur connecté et il n’y a aucun signe d’erreurs ou d’exceptions en cours d’exécution.

Les combinés que j’utilise sont:

Windows Phone 7 – Nokia Lumia 900 (* 2), Nokia Lumia 800 (* 3) Windows Phone 8 – Nokia Lumia 920 (* 1), Nokia Limia 820 (* 2)

Celles-ci utilisent toutes le dernier système d’exploitation et sont en mode développeur. L’environnement de développement est Windows 8 Enterprise exécutant Visual Studio 2012 Professional

Je ne peux pas vous en dire beaucoup sur le réseau sans fil de travail – autre que les appareils Phone 7 n’ont aucun problème.

En ce qui concerne le réseau sans fil domestique que j’ai utilisé, il ne s’agit que d’un routeur BT haut débit de base sans aucun des parameters «externes» modifiés.

De toute évidence, la configuration des deux réseaux pose problème, mais la manière dont Windows Phone 8 implémente les messages UDP pose également problème.

Toute consortingbution serait appréciée car cela me rend fou en ce moment.

Je remarque que vous utilisez le bouclage. Je pense que cela signifie que lorsque vous envoyez un message de votre client, vous recevrez également le message que vous avez envoyé. Cela signifie que votre gestionnaire de réception se déclenche. Cela a pour effet d’effacer le tampon de réception d’une manière apparemment irréprochable. Essayez de mettre un certain try catch dans votre méthode de réception et voyez si quelque chose de fâcheux se produit, mais au lieu de cela, vous pourriez ne pas utiliser le tampon de réception partagé.

Avez-vous déjà essayé de rejoindre un autre groupe de multidiffusion? Parce que 224.0.1.1 semble être utilisé à partir des assignations IANA. Vous trouvez tous les ici .

Peut-être que sur Windows Phone 8, un service est plus étroitement lié à l’écoute des messages entrants (par exemple, un service réseau exécuté en mode kernel) et qu’ils ne vous sont jamais transmis.

UDP multicast fonctionne étrangement sous Windows Phone 7 de mon expérience, donc vous devriez vérifier la même chose pour Windows Phone 8.

Voici mon expérience:

  1. vérifiez ce qui est officiellement supporté, par exemple sous Windows Phone OS 7.1 (dernier système d’exploitation que j’ai essayé avant de basculer), les clients TCP unicast, UDP unicast et UDP multicast sont pris en charge.
  2. Certaines versions de Windows Phone permettent de recevoir une session UDP uniquement si le client l’a d’abord ouvert et que la session a été reçue en moins de 10 secondes, cela semble être une sorte de sécurité sur Windows Phone.
  3. essayez avec des adresses différentes: les adresses multicast comsockets entre 224.0.0.0 et 224.0.0.255 inclus sont des adresses multicast réservées «connues».
  4. Vérifiez à la fois sur la machine virtuelle et sur un appareil téléphonique réel, le comportement peut différer.