3

I managed to make a simple application that sends and receives data from a multicast group. If I open 2 instance of the application (2 different .sln files with the same code) I can send and receive data. The problem is that after 5 seconds, if I send a message from the Client001 only the Client001 will get the message. But, if I send message from the Client002 (the second instance of the app) within the 5 seconds then both of them get the message. I had an example with UdpClient that was working perfectly, but that is no longer available for UWP. So in conclusion, how can I achieve, no matter when (not within 5 seconds) some of the clients sends a message, all of the other clients get it?

This is the code for the MainPage.xaml.cs

namespace Client001
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private DatagramSocket listenerSocket = null;
        public string remoteAddress = "224.3.0.5";
        HostName remoteHostname;
        public string serviceName = "22113";
        IOutputStream outputStream;
        DataWriter writer;

        public MainPage()
        {
            this.InitializeComponent();
            SetupMulticastScenarioUI();

            remoteHostname = new HostName(RemoteAddress.Text);
        }

        private void CloseListenerSocket()
        {
            if (listenerSocket != null)
            {
                // DatagramSocket.Close() is exposed through the Dispose() method in C#.
                // The call below explicitly closes the socket, freeing the UDP port that it is currently bound to.
                listenerSocket.Dispose();
                listenerSocket = null;
            }
        }

        // Sets up the UI to display the multicast scenario options.
        private void SetupMulticastScenarioUI()
        {
            RemoteAddress.Text = remoteAddress;
            ServiceName.Text = serviceName;
            StartListener.Content = "Start listener and join multicast group";
            SendMessageButton.IsEnabled = false;
            CloseListenerButton.IsEnabled = false;
            SendOutput.Text = "";
        }

        private async void StartListener_Click(object sender, RoutedEventArgs e)
        {
            listenerSocket = new DatagramSocket();

            listenerSocket.Control.MulticastOnly = true;
            await listenerSocket.BindServiceNameAsync(ServiceName.Text);

            // Join the multicast group to start receiving datagrams being sent to that group.
            listenerSocket.JoinMulticastGroup(remoteHostname);

            listenerSocket.MessageReceived += MessageReceived;
            SendOutput.Text = "Listening on port " + listenerSocket.Information.LocalPort + " and joined to multicast group";

            // Enable scenario steps that require us to have an active listening socket.
            SendMessageButton.IsEnabled = true;
            CloseListenerButton.IsEnabled = true;

            outputStream = await listenerSocket.GetOutputStreamAsync(remoteHostname, ServiceName.Text);
            writer = new DataWriter(outputStream);
            writer.WriteString("Handshake1");
            await writer.StoreAsync();
        }

        private async void SendMessage_Click(object sender, RoutedEventArgs e)
        {
            writer.WriteString(Message.Text);
            await writer.StoreAsync();
        }

        private void CloseListener_Click(object sender, RoutedEventArgs e)
        {
            CloseListenerSocket();

            // Disable scenario steps that require us to have an active listening socket.
            SendMessageButton.IsEnabled = false;
            CloseListenerButton.IsEnabled = false;
            SendOutput.Text = "";

            SendOutput.Text = "Listener closed";
        }

        async void MessageReceived(DatagramSocket socket, DatagramSocketMessageReceivedEventArgs eventArguments)
        {
            // Interpret the incoming datagram's entire contents as a string.
            uint stringLength = eventArguments.GetDataReader().UnconsumedBufferLength;
            string receivedMessage = eventArguments.GetDataReader().ReadString(stringLength);

            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                SendOutput.Text = "Received data from remote peer (Remote Address: " +
                    eventArguments.RemoteAddress.CanonicalName + ", Remote Port: " +
                    eventArguments.RemotePort + "): \"" + receivedMessage + "\"";
            });
        }
    }
}

This is the code for the MainPage.xaml

<Page
    x:Class="Client001.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Client001"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">


    <StackPanel>
        <TextBlock>Remote Address:</TextBlock>
        <TextBox x:Name="RemoteAddress" />

        <TextBlock>Service Name:</TextBlock>
        <TextBox x:Name="ServiceName" />

        <Button x:Name="StartListener" Click="StartListener_Click" Margin="0,10,0,0"/>
        <Button x:Name="SendMessageButton" Content="Send 'hello'" Click="SendMessage_Click" Margin="0,10,0,0"/>
        <Button x:Name="CloseListenerButton" Content="Close Listener" Click="CloseListener_Click" Margin="0,10,0,0"/>
        <TextBlock x:Name="SendOutput" TextWrapping="Wrap"  Margin="0,10,0,0"/>
        <TextBox x:Name="Message"></TextBox>
    </StackPanel>

</Page>

UPDATE: After a bit of searching i found out that maybe the TTL(Time To Live) is the problem, but I still don't know how to fix this issue.

Stefan
  • 188
  • 2
  • 19

1 Answers1

3

So in conclusion, how can I achieve, no matter when (not within 5 seconds) some of the clients sends a message, all of the other clients get it?

It seems like that this issue has been fixed in the latest Windows RS1(Build 14393) OS, here is the screenshot(Gif): enter image description here

You may need to upgrade the OS to solve it.

Franklin Chen - MSFT
  • 4,845
  • 2
  • 17
  • 28
  • Thank you so much for your answer. If it's not much trouble please take a look at [this](http://stackoverflow.com/questions/38684400/event-handler-is-executed-more-than-once) question, and see if that problem is solved as well. – Stefan Aug 03 '16 at 14:39
  • @Stefan I will check it if I back to office:) So, is this answer answered your question?:) – Franklin Chen - MSFT Aug 03 '16 at 14:42
  • I am just updating my Windows 10 to the latest version, so I will let you know. – Stefan Aug 03 '16 at 14:48
  • @Stefan If there is no changes, please also upgrade VS, ensure the latest patches and Tools for Universal Windows Apps has been installed – Franklin Chen - MSFT Aug 03 '16 at 17:00
  • The Windows 10 update just finished and I tried the application again. I am happy to inform you that it works. But now i come across another issue. When I start the listeners on both apps and send a message from the first app, only the first app gets the message. When the second app sends a message, only then it will begin to receive messages from the other app. Is there any solution to fix this issue? – Stefan Aug 03 '16 at 17:14
  • @Stefan Ok, I will check this new issue later and inform the related team if I can reproduce it. – Franklin Chen - MSFT Aug 03 '16 at 17:18
  • The second issue seems due to this DatagramSocket bug http://stackoverflow.com/questions/39696995/listening-to-broadcasts-when-server-and-client-are-on-the-same-machine – José Dec 16 '16 at 21:31