问题
I am trying to setup a TCP connection between two UWP apps. It works fine when both server and client are running in the same app. But when I move the server part to one app and the client part to another, the ConnectAsync throws an exception (server does not respond in time).
Both apps have the private networks capability setup. And as I understand from the MSDN pages I don't have to bother with adding an exception in CheckNetIsolation as long as I run the apps in the debugger. (I checked the checkbox in de debug property pages of the project, both have the "Allow local network loopback" enabled.
Firewall is turned off completely too.
I can see in netstat that the port is opened and that it's in the listening state:
TCP 0.0.0.0:1337 PC-BAS:0 LISTENING
The code I am using is copied from the MSDN example and is unchanged, except for the part the client and server are hosted in two separate apps.
Client:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//this.StartServer();
this.StartClient();
}
private async void StartClient()
{
try
{
// Create the StreamSocket and establish a connection to the echo server.
using (var streamSocket = new Windows.Networking.Sockets.StreamSocket())
{
// The server hostname that we will be establishing a connection to. In this example, the server and client are in the same process.
var hostName = new Windows.Networking.HostName("127.0.0.1");
this.clientListBox.Items.Add("client is trying to connect...");
await streamSocket.ConnectAsync(hostName, StreamSocketAndListenerPage.PortNumber);
this.clientListBox.Items.Add("client connected");
// Send a request to the echo server.
string request = "Hello, World!";
using (Stream outputStream = streamSocket.OutputStream.AsStreamForWrite())
{
using (var streamWriter = new StreamWriter(outputStream))
{
await streamWriter.WriteLineAsync(request);
await streamWriter.FlushAsync();
}
}
this.clientListBox.Items.Add(string.Format("client sent the request: \"{0}\"", request));
// Read data from the echo server.
string response;
using (Stream inputStream = streamSocket.InputStream.AsStreamForRead())
{
using (StreamReader streamReader = new StreamReader(inputStream))
{
response = await streamReader.ReadLineAsync();
}
}
this.clientListBox.Items.Add(string.Format("client received the response: \"{0}\" ", response));
}
this.clientListBox.Items.Add("client closed its socket");
}
catch (Exception ex)
{
Windows.Networking.Sockets.SocketErrorStatus webErrorStatus = Windows.Networking.Sockets.SocketError.GetStatus(ex.GetBaseException().HResult);
this.clientListBox.Items.Add(webErrorStatus.ToString() != "Unknown" ? webErrorStatus.ToString() : ex.Message);
}
}
Server:
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
try
{
var streamSocketListener = new Windows.Networking.Sockets.StreamSocketListener();
// The ConnectionReceived event is raised when connections are received.
streamSocketListener.ConnectionReceived += this.StreamSocketListener_ConnectionReceived;
// Start listening for incoming TCP connections on the specified port. You can specify any port that's not currently in use.
await streamSocketListener.BindServiceNameAsync("1337");
}
catch (Exception ex)
{
Windows.Networking.Sockets.SocketErrorStatus webErrorStatus = Windows.Networking.Sockets.SocketError.GetStatus(ex.GetBaseException().HResult);
}
}
private async void StreamSocketListener_ConnectionReceived(Windows.Networking.Sockets.StreamSocketListener sender, Windows.Networking.Sockets.StreamSocketListenerConnectionReceivedEventArgs args)
{
string request;
using (var streamReader = new StreamReader(args.Socket.InputStream.AsStreamForRead()))
{
request = await streamReader.ReadLineAsync();
}
// Echo the request back as the response.
using (Stream outputStream = args.Socket.OutputStream.AsStreamForWrite())
{
using (var streamWriter = new StreamWriter(outputStream))
{
await streamWriter.WriteLineAsync(request);
await streamWriter.FlushAsync();
}
}
sender.Dispose();
}
What am I doing wrong?
Update
I tried to excempt both apps with checknetisolation:
C:\Users\baspr>checknetisolation LoopbackExempt -s
List Loopback Exempted AppContainers
1 ----------------------------------------------------------------- Name: bb9c7c66-7c8e-4736-b328-1b107e10a7a9_wkb2562a8jp2j SID: S-1-15-2-762432806-102046223-720402593-3591906639-2980959523-756744333-221970472
[2] ----------------------------------------------------------------- Name: client_wkb2562a8jp2j SID: S-1-15-2-2445159625-2135182799-200836335-1591194441-3000767028-3156876117-3345333685
client:
C:\Users\baspr>checknetisolation LoopbackExempt -a -n=client_wkb2562a8jp2j
OK.
server:
C:\Users\baspr>checknetisolation LoopbackExempt -a -n=bb9c7c66-7c8e-4736-b328-1b107e10a7a9_wkb2562a8jp2j
OK.
Although I wonder if that's even necessary as this is stated on MSDN :
Loopback and the debugger
By default, running under the Visual Studio debugger enables outbound loopback automatically for that debug session only. You shouldn’t have to do anything as long as the loopback checkbox is checked in the debugger settings for your startup project. If you want to implement a socket listener the you must enable localhost loopback for inbound connections (see below).
In any event, it doesn't change anything. I still can't connect to the server. I tried both my local IP address as the loopback address (192.168.1.2 and 127.0.0.1). It doesn't work.
Hope anybody can shed a light on this ...
来源:https://stackoverflow.com/questions/56610586/uwp-unable-to-create-localhost-connection-between-two-apps