Я пытаюсь настроить TCP-соединение между двумя приложениями UWP. Он отлично работает, когда сервер и клиент работают в одном приложении. Но когда я перемещаю серверную часть в одно приложение, а клиентскую часть - в другое, ConnectAsync выдает исключение (сервер не отвечает вовремя).
Оба приложения имеют возможность настройки частных сетей. И, как я понимаю из страниц MSDN, мне не нужно беспокоиться о добавлении исключения в CheckNetIsolation, пока я запускаю приложения в отладчике. (Я установил флажок на страницах свойств de debug проекта, на обоих включен «Разрешить петлю локальной сети».
Брандмауэр тоже полностью отключен.
В netstat
я вижу, что порт открыт и находится в состоянии прослушивания:
TCP 0.0.0.0:1337 PC-BAS:0 LISTENING
Код, который я использую, скопирован из примера MSDN и не изменяется, за исключением части, в которой клиент и сервер размещены в двух отдельных приложениях.
Клиент:
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);
}
}
Сервер:
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();
}
Что я делаю не так?
Обновление
Я пытался исключить оба приложения с помощью checknetisolation
:
C: \ Users \ baspr> checknetisolation LoopbackExempt -s
Список зацикленных исключений AppContainers
1 ---------------------------------------- -------------------------
Имя: bb9c7c66-7c8e-4736-b328-1b107e10a7a9_wkb2562a8jp2j
SID: S-1-15-2-762432806-102046223-720402593-3591906639-2980959523-756744333-221970472
[2] -------------------------------------------- ---------------------
Имя: client_wkb2562a8jp2j
SID: S-1-15-2-2445159625-2135182799-200836335-1591194441-3000767028-3156876117-3345333685
клиент:
C:\Users\baspr>checknetisolation LoopbackExempt -a -n=client_wkb2562a8jp2j
OK.
Сервер:
C:\Users\baspr>checknetisolation LoopbackExempt -a -n=bb9c7c66-7c8e-4736-b328-1b107e10a7a9_wkb2562a8jp2j
OK.
Хотя мне интересно, если это вообще необходимо, как указано в MSDN:
Loopback и отладчик
По умолчанию запуск в отладчике Visual Studio включает исходящие
loopback автоматически только для этого сеанса отладки. Вы не должны
должны сделать что-нибудь, пока флажок зацикливания установлен в
настройки отладчика для вашего запуска проекта. Если вы хотите реализовать
слушатель сокета, вы должны включить локальную петлю для входящего
соединения (см. ниже).
В любом случае это ничего не меняет. Я все еще не могу подключиться к серверу. Я попробовал оба своих локальных IP-адреса в качестве петлевого адреса (192.168.1.2 и 127.0.0.1). Не работает
Надеюсь, что кто-нибудь может пролить свет на это ...