Metro Nuggets

Bitesized tidbits for building Modern (Metro) apps.

How to Send and Receive a UDP Broadcast in Windows Phone 8 (and Win8)

I’m sure you’ve seen plenty of mobile apps that do a search for a device on the network (say a bluray player) and it magically finds your device on your network. Looks pretty cool, right? Would be great to add that into your app wouldn’t it. Well, as long as you’re not developing for Windows Phone 7, then I will show how.

The Solution

As mentioned, this is only for Windows Phone 8 and Windows 8 as Windows Phone 7 doesn’t support receiving from a UDP broadcast, you can send the message out, but you won’t get any of the responses; you’d need to do a multicast communications for WP7.

So then, the code. This bit of code magically works on both Windows Phone 8 and Windows 8 without any alteration, gotta love that shared networking stack, right!

private async Task SendMessage(string message, int port)
{
    var socket = new DatagramSocket();

    socket.MessageReceived += SocketOnMessageReceived;

    using (var stream = await socket.GetOutputStreamAsync(new HostName("255.255.255.255"), port.ToString()))
    {
        using (var writer = new DataWriter(stream))
        {
            var data = Encoding.UTF8.GetBytes(message);

            writer.WriteBytes(data);
            writer.StoreAsync();
        }
    }
}

private async void SocketOnMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    var result = args.GetDataStream();
    var resultStream = result.AsStreamForRead(1024);

    using (var reader = new StreamReader(resultStream))
    {
        var text = await reader.ReadToEndAsync();
        Deployment.Current.Dispatcher.BeginInvoke(() =>
                                                        {
                                                            // Do what you need to with the resulting text
                                                            // Doesn't have to be a messagebox
                                                            MessageBox.Show(text);
                                                        });
    }
}

That’s all you need to do. Really, it is.

SL

20 responses to “How to Send and Receive a UDP Broadcast in Windows Phone 8 (and Win8)

  1. Pingback: How to Send and Receive a UDP Broadcast in Windows Phone 8 (and Win8)

  2. RagBuster (@RagBuster) April 6, 2013 at 11:25

    Thanks for this snippet of code, Works great on some windows phone 8 code I am trying. How long does the receive process last for? I have sent a SSDP request and seem to receive all the data but is the app always listening?

  3. Mike October 6, 2013 at 08:37

    Where is the windows.networking DLL and how do I add it to a WP8 app? I can’t find it anywhere!!

  4. CanadaCoder October 27, 2013 at 19:57

    Thank you for sharing
    I’m sorry for bothering you but would you please ask my question below?
    Is it also possible to receive unicast UDP packets? Or just broadcast receiving is supported?
    Thank you very much
    Regards

  5. Dan November 20, 2013 at 10:00

    I’ve tried your Solution but it does not appear to send anything over the Network. I am listening with wireshark. ID_CAP_NETWORKING is checked. Any ideas?
    Thank you.

  6. Torsten Zetpunkt January 27, 2014 at 17:43

    Hi. Thank you for sharing the code.

    Can you please tell me how the listener works? I tried different things it doens’t work for me. On which port is it listening? And it starts listening first, when I first sendet a message to broadcast right?

    Thanks in advance.

  7. scottisafool January 27, 2014 at 17:48

    The port is whatever you want it to be, but it must be the one the server end is listening out for. So if you have something listening on port 666, you should broadcast out to port 666.

    • Torsten Zetpunkt January 27, 2014 at 18:19

      Sorry if I asked wrong… I mean there is the SocketOnMessageReceived-method. Isn’t it waiting for a reply? I don’t know how to use this method. I can send out messages from the Windows Phone to a udp-server port 666. The message is received correctly. Then I try to reply from the server and send “hello” to the Windows Phone. But nothing happens in the App. I hoped that a messagebox appears with “hello” in it.

      • scottisafool January 27, 2014 at 18:25

        Yes, it is waiting for a response. It won’t just show a messagebox unless you’ve told it to. If you have used the code above then it should. If you put a break point in the received handler, does it get hit?

  8. Torsten Zetpunkt January 27, 2014 at 18:38

    I use the code above. The received handler does not hit the breakpoint…

  9. sleepingshorty January 27, 2014 at 18:50

    This is my Code. I added a comment with breakpoint. I also added a MessageBox that should appear when the Received-Event is triggered but nothing happens.

    I wasn’t sure if my udp packed was correctly send to the Phone but I sniffed it an it is send correctly.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    using Microsoft.Phone.Controls;
    using Microsoft.Phone.Shell;
    using AsyncUDP.Resources;
    using System.Threading.Tasks;
    using Windows.Networking.Sockets;
    using System.Text;
    using Windows.Networking;
    using System.IO;
    using Windows.Storage.Streams;

    namespace AsyncUDP
    {
    public partial class MainPage : PhoneApplicationPage
    {
    int i = 0;
    public MainPage()
    {
    InitializeComponent();
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
    SendMessage(“Hello “+ i + “\n”, 1337);
    i++;
    }

    private async Task SendMessage(string message, int port)
    {
    var socket = new DatagramSocket();

    socket.MessageReceived += SocketOnMessageReceived;

    using (var stream = await socket.GetOutputStreamAsync(new HostName(“255.255.255.255”), port.ToString()))
    {
    using (var writer = new DataWriter(stream))
    {
    var data = Encoding.UTF8.GetBytes(message);

    writer.WriteBytes(data);
    writer.StoreAsync();
    }
    }
    }

    private async void SocketOnMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
    {
    //BREAK POINT
    MessageBox.Show(“Received a Message!”);
    var result = args.GetDataStream();
    var resultStream = result.AsStreamForRead(1024);
    using (var reader = new StreamReader(resultStream))
    {
    var text = await reader.ReadToEndAsync();
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
    MessageBox.Show(text);
    });
    }
    }

    }

    }

  10. raptor May 7, 2015 at 19:40

    i cannot use Deployment.Current.Dispatcher.BeginInvoke(() . It gives me error name Deployment could not be found in current context. ? please help;

    • ccristocea May 16, 2015 at 20:26

      Try this . It is working well.
      tb1 & tb2 are TextBox and bt1 is “Send” button.
      Not running on the same machine but if you use Hyper-V, it can communicate very easily. Virtual PC is Win Server 2008 and .Net UDPClient running program uses Windows Form. You can get it here:
      http://www.dreamincode.net/forums/topic/231058-peer-to-peer-chat-advanced/

      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Runtime.InteropServices.WindowsRuntime;
      using System.Text;
      using System.Threading.Tasks;
      using Windows.Foundation;
      using Windows.Foundation.Collections;
      using Windows.Networking;
      using Windows.Networking.Sockets;
      using Windows.Storage.Streams;
      using Windows.UI.Xaml;
      using Windows.UI.Xaml.Controls;
      using Windows.UI.Xaml.Controls.Primitives;
      using Windows.UI.Xaml.Data;
      using Windows.UI.Xaml.Input;
      using Windows.UI.Xaml.Media;
      using Windows.UI.Xaml.Navigation;

      namespace ChatTestStore2
      {

      public sealed partial class MainPage : Page
      {
      DatagramSocket socket = new DatagramSocket();

      int port;
      public MainPage()
      {
      this.InitializeComponent();

      port = 54545;
      StartListener(port);
      }
      private async void StartListener( int port)
      {
      socket.MessageReceived += SocketOnMessageReceived;
      await socket.BindServiceNameAsync(port.ToString());
      }

      private async Task SendMessage(string message, int port)
      {

      using (var stream = await socket.GetOutputStreamAsync(new HostName(“255.255.255.255″), port.ToString()))
      {
      using (var writer = new DataWriter(stream))
      {
      var data = Encoding.UTF8.GetBytes(message);

      writer.WriteBytes(data);
      await writer.StoreAsync();

      }
      }

      }

      private async void SocketOnMessageReceived(DatagramSocket soket, DatagramSocketMessageReceivedEventArgs eventArguments)
      {

      // si asta e ff bun
      var result = eventArguments.GetDataStream();
      var resultStream = result.AsStreamForRead(1024);

      using (var reader = new StreamReader(resultStream))
      {
      string text = await reader.ReadToEndAsync();
      await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
      () =>
      {
      tb2.Text = text;
      // Do what you need to with the resulting text
      });
      }
      /*
      // this work as well
      try
      {
      uint stringLength = eventArguments.GetDataReader().UnconsumedBufferLength;
      string command = eventArguments.GetDataReader().ReadString(stringLength);

      await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
      {
      tb2.Text = command + ” ( ” + DateTime.Now +”)”;
      // MakeMove(command);
      }
      );
      }
      catch (Exception exception)
      {
      SocketErrorStatus socketError = SocketError.GetStatus(exception.HResult);
      if (socketError == SocketErrorStatus.ConnectionResetByPeer)
      {
      Debug.WriteLine(“Peer does not listen on the specific port. Please make sure that you run step 1 first ” +
      “or you have a server properly working on a remote server.”);
      }
      else if (socketError != SocketErrorStatus.Unknown)
      {
      Debug.WriteLine(“Error happened when receiving a datagram: ” + socketError.ToString());
      }
      else
      {
      throw;
      }
      }
      */
      }

      private async void bt1_Click(object sender, RoutedEventArgs e)
      {
      await SendMessage(“Me: \n”+tb1.Text,port);
      }

      }
      }

  11. jas February 22, 2017 at 18:04

    Just to pull out the minimum change required, the below two lines of code are the change required to make the listener MessageReceived events fire.

    socket.MessageReceived += SocketOnMessageReceived;
    await socket.BindServiceNameAsync(port.ToString());<====== this binds the socket for incoming data.

Leave a reply to Torsten Zetpunkt Cancel reply