Network connection with UWP Apps

天大地大妈咪最大 提交于 2019-12-08 22:32:15

问题


I got two Windows UWP Apps. One of them (the "server") is running on a Raspberry Pi 2 on Windows IoT (10586.0). The other (the "client") is running on any Windows 10 device within the same network.

What I want is to get the apps to "talk" to each other. For the moment I just want to send simple String from the client to the server. Later on, serialized data should be transferred trough the network.

This is the code for the server App:

namespace LCARSHomeAutomation
{
/// <summary>
/// Eine leere Seite, die eigenständig verwendet oder zu der innerhalb eines Rahmens navigiert werden kann.
/// </summary>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();

        try {
            EstablishNetworking();
            txb_Events.Text += "Server Running";
        }catch (Exception ex)
        {
            txb_Events.Text += ex.Message;
        }


    }

    private async void EstablishNetworking()
    {
        await StartListener();
    }

    public async Task StartListener()
    {
        StreamSocketListener listener = new StreamSocketListener();
        listener.ConnectionReceived += OnConnection;

        listener.Control.KeepAlive = true;

        try
        {
            await listener.BindServiceNameAsync("5463");

        }
        catch (Exception ex)
        {
            if (SocketError.GetStatus(ex.HResult) == SocketErrorStatus.Unknown)
            {
                throw;
            }
            //Logs.Add(ex.Message);
            txb_Events.Text += ex.Message;
        }

    }

    private async void OnConnection(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
    {
        Stream inStream = args.Socket.InputStream.AsStreamForRead();
        StreamReader reader = new StreamReader(inStream);
        string request = await reader.ReadLineAsync();

        await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                                   () =>
                                   {
                                        // Your UI update code goes here!
                                        txb_Events.Text += (String)request;
                                   });


    }

    private async Task ConnectSocket()
    {
        StreamSocket socket = new StreamSocket();

        socket.Control.KeepAlive = false;

        HostName host = new HostName("localhost");

        try
        {
            await socket.ConnectAsync(host, "5463");

            Stream streamOut = socket.OutputStream.AsStreamForWrite();
            StreamWriter writer = new StreamWriter(streamOut);
            string request = "Test Self App \n";
            await writer.WriteLineAsync(request);
            await writer.FlushAsync();

            socket.Dispose();
        }
        catch (Exception ex)
        {
            txb_Events.Text += ex.Message;
            //Logs.Add(ex.Message)
        }


    }

    private async void btn_Send_Click(object sender, RoutedEventArgs e)
    {
        await ConnectSocket();
    }

}
}

As you can see, I'm establishing a network connection with the same app on the same host and send the string "Test Self App". This works fine for quite some time but after a while I get the Error:

Exception thrown: 'System.Runtime.InteropServices.COMException' in mscorlib.ni.dll

WinRT information: No connection could be made because the target machine actively refused it.

So, this is my first question: What is this Error and how can I fix this?

The other thing is: I'm not able to establish a network Connection between the server and the Client. I don't know, what I am doing wrong. This is the code of the "Client":

namespace LCARSRemote
{
/// <summary>
/// Eine leere Seite, die eigenständig verwendet oder zu der innerhalb eines Rahmens navigiert werden kann.
/// </summary>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    private async void btn_Send_Click(object sender, RoutedEventArgs e)
    {
        StreamSocket socket = new StreamSocket();

        HostName host = new HostName("localhost"); //Replace with coorect hostname when running on RPi

        try
        {
            try {
                await socket.ConnectAsync(host, "5463");
            }
            catch(Exception ex)
            {
                txb_Events.Text += ex.Message;
            }

            Stream streamOut = socket.OutputStream.AsStreamForWrite();
            StreamWriter writer = new StreamWriter(streamOut);
            string request = "Remote App Test";
            await writer.WriteLineAsync(request);
            await writer.FlushAsync();

            socket.Dispose();

        }
        catch (Exception ex)
        {
            txb_Events.Text += ex.Message;
            //Logs.Add(ex.Message)
        }

    }
}
}

When I click on the btn_Send, I get the error message

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

and

A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)

What am I doing wrong? Maybe I should say, that I'm relatively new in programming network connections, sockets etc.

Thanks for any help!


回答1:


You should try using StreamSocket API in UWP. This sample repo contents both server and client code: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/StreamSocket

A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)

This error happened for me when I try to call ConnectAsync twice in a row, I think you can check your logic or debug to confirm in your case.




回答2:


The first error

Exception thrown: 'System.Runtime.InteropServices.COMException' in mscorlib.ni.dll

WinRT information: No connection could be made because the target machine actively refused it.

This is because the socket is still open with a previous request and has not closed yet. So catch this error and try and to reconnect.

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

This is because the server and client are on the same machine, I a running into this same problem supposedly you can run from an elevated command prompt

checknetisolation loopbackexempt -d -n= {package family} 

to resolve it.

This solution did not work for me. So your server must run on a pi and client must run on your desktop PC for windows 10 UWP to be able to connect to it. Windows 10 does not allow loopback connection for UWP applications as far as I can tell.

If you truly want to run a socket server/web server node.js windows universal apps might be a good approach

https://ms-iot.github.io/content/en-US/win10/samples/NodejsWU.htm

or

RestUP  https://github.com/tomkuijsten/restup



回答3:


Depending how much data you're talking about and what the end use case is, Amazon's AWS IoT Platform might be something to look at. It's pretty cool for a number of reasons. Specifically I like that the target device can be offline at the time of transmission.

It's free (250,000 messages) for the first year and $5 per one million messages after that. Every 512 byte block counts as 1 message credit.



来源:https://stackoverflow.com/questions/36475752/network-connection-with-uwp-apps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!