5

I've been trying to setup a client server between a UWP app as the client and a .NET desktop app as the server. I'm using UDP Datagrams as the messaging system between the two.

Here my UWP code to listen for Datagrams on the localhost IP at port 22222:

private async void listenToServer()
{
    // Setup UDP Listener
    socketListener = new DatagramSocket();
    socketListener.MessageReceived += MessageReceived;

    await socketListener.BindEndpointAsync(new HostName("127.0.0.1"),"22222");
    Debug.WriteLine("Listening: " + socketListener.Information.LocalAddress + " " + socketListener.Information.LocalPort);
 }

private async void MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    // Interpret the incoming datagram's entire contents as a string.
    uint stringLength = args.GetDataReader().UnconsumedBufferLength;
    string receivedMessage = args.GetDataReader().ReadString(stringLength);
    Debug.WriteLine("Received " + receivedMessage);
}

Here is my WinForm .NET desktop app to send Datagrams on localhost on port 2222:

public async void sendToClient()
{
    // Setup UDP Talker
    talker = new UdpClient();
    sending_end_point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 22222);
    talker.Connect(sending_end_point);

    byte[] send_buffer = Encoding.ASCII.GetBytes("Hello!");
    await talker.SendAsync(send_buffer, send_buffer.Length);
}

Here is what I've tried, and what I know from my troubleshooting:

  1. Sending a UDP datagram from UWP to .NET desktop works.

    UWP code to send message to .NET desktop over localhost port 11111:

    public async void sendToServer()
    {
        // Connect to the server
        socketTalker = new DatagramSocket();
        await socketTalker.ConnectAsync(new HostName("127.0.0.1"), "11111");
        Debug.WriteLine("Connected: " + socketTalker.Information.RemoteAddress + " " + socketTalker.Information.RemotePort);
    
        // Setup Writer
        writer = new DataWriter(socketTalker.OutputStream);
        writer.WriteString("Ping!");
    
        await writer.StoreAsync();
    
        writer.DetachStream();
        writer.Dispose();
    }
    

    .NET desktop code to listen for message from UWP over same IP and port:

    private async Task listenToClient()
    {
        // Setup listener
        listener = new UdpClient(11111);
        UdpReceiveResult receiveResult = await listener.ReceiveAsync();
        Debug.WriteLine(" Received: " + Encoding.ASCII.GetString(receiveResult.Buffer));
    
    }
    
  2. Sending UDP Datagram from .NET desktop to UWP works across different IPs (2 different computers)

    I've tested this by setting the listener and talker IP addresses to the same IP address where the server was running, and it works flawlessly. This lead to research which got me to #3...

  3. Loopback exemption didn't make a difference

    Running CheckNetIsolation.exe and the Loopback exemption tool to exempt the UWP app from loopback IP restriction didn't fix this issue. It seems it shouldn't matter, from what I read (Problems with UDP in windows 10. UWP), running in the Visual Studio environment should already be exempt from loopback, but I tried anyways, and not luck.

Sammy Guergachi
  • 1,986
  • 4
  • 26
  • 52

1 Answers1

4

As much as this sucks, it is blocked by Microsoft by design.

Loopback is permitted only for development purposes. Usage by a Windows Runtime app installed outside of Visual Studio is not permitted. Further, a Windows Runtime app can use an IP loopback only as the target address for a client network request. So a Windows Runtime app that uses a DatagramSocket or StreamSocketListener to listen on an IP loopback address is prevented from receiving any incoming packets.

Source: https://msdn.microsoft.com/en-us/library/windows/apps/hh780593.aspx

The best workaround you can do is to use TCP sockets and connect from the UWP app to your desktop app (not the other way around).

Sunius
  • 2,789
  • 18
  • 30
  • As I said in point #3, this doesn't work even in Visual Studio *with* loopback exemption, it must be something else. In addition, why would it work one way (UWP to .NET) and not the otherway (.NET to UWP)? – Sammy Guergachi Jul 08 '17 at 21:51
  • 1
    Read this again: "Further, a Windows Runtime app can use an IP loopback only as the target address for a client network request. So a Windows Runtime app that uses a DatagramSocket or StreamSocketListener to listen on an IP loopback address is prevented from receiving any incoming packets.". Even with loopback exemption you cannot get around this. – Sunius Jul 09 '17 at 20:10
  • Does that mean that there's no way for the desktop app to send messages to the UWP app (even with TCP sockets)? – Sammy Guergachi Jul 16 '17 at 22:25
  • 1
    There is. Desktop app must open a TCP socket and listen/accept connections from it, and UWP app has to connect to it. Once connected, data can be sent both ways. – Sunius Jul 18 '17 at 04:13
  • 1
    Problem is that they don't treat 127.0.0.1 as loopback address, but also the machine's full IP address (could pass that traffic through the firewall if they wanted to be "safe") and also have issues if you try to use a VM etc. And people get confused with all the talk about loopback exceptions that don't apply to server (listening) sockets for yet another unexplained reason. Don't see how the OS is more secure with such requirements, they just crippled UWP apps – George Birbilis Aug 28 '17 at 22:34
  • Yup, I totally agree with you. I think that blocking makes no sense. – Sunius Aug 29 '17 at 03:51