question

Madhu-8808 avatar image
0 Votes"
Madhu-8808 asked ·

UWP app System.Net.Sockets - localhost

Hi,

When reading about sockets in UWP, I have seen that we can't use sockets to communicate between 2 apps in the same device with localhost. (Not sure exactly when it works and not).

I just need to clarify on that. If I connect to some other app running in the same device as my UWP app, should I be able to connect to that other app using System.Net.Sockets? Or it is not allowed?
My UWP app will be the client and there will be another app (most probably .net app) which works as the server. So if I call the server from my app like this it seems to work. But based on some articles I am not sure whether there are any restrictions on this. Will this work in a UWP app submitted to Store or will there be issues?

            clientSocket = new Socket(AddressFamily.InterNetwork,
            SocketType.Dgram, ProtocolType.Udp);

             //IP address of the server machine
             IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
             //Server is listening on port 1000
             IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 1000);

             epServer = (EndPoint)ipEndPoint;
             clientSocket.BeginSendTo(byteData, 0, byteData.Length, SocketFlags.None, epServer, new AsyncCallback(OnSend), null);


Update : please see the Note here. https://docs.microsoft.com/en-us/windows/uwp/networking/sockets
It says 'Windows disallows establishing a socket connection (Sockets or WinSock) between two UWP apps running on the same machine'. So this applies only for 2 UWP apps? If one is a UWP app and the other is a .net app then it will not be an issue?

Thanks
Madhu

windows-uwp
· 1
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Desktop bridge app is acceptable for Microsoft Store, so you can convert win32 app to UWP app to publish it. But when submitting, you will need to fill in some additional information and the store team will review your submission. After passing the review, the app will show in the store.

1 Vote 1 · ·
PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered ·

Hi,
there's no problem to use sockets in UWP. Try following demo:

XAML

 <Page
     x:Class="UWP10App1VB.Page13"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="using:UWP10App1VB"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     mc:Ignorable="d"
     Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
   <Page.Resources>
     <local:Page13VM x:Key="vm"/>
   </Page.Resources>
   <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
               DataContext="{StaticResource vm}">
     <Button Content="Receive" Command="{Binding Cmd}"/>
     <TextBlock Text="{Binding Display, Mode=OneWay}"/>
   </StackPanel>
 </Page>

Code

 Imports System.Net
 Imports System.Net.Sockets
 Imports System.Threading
 Imports Newtonsoft.Json
 Imports Windows.Networking
 Imports Windows.Networking.Sockets
    
 ''' <summary>
 ''' An empty page that can be used on its own or navigated to within a Frame.
 ''' </summary>
 Public NotInheritable Class Page13
   Inherits Page
    
 End Class
    
 Public Class Page13VM
   Implements INotifyPropertyChanged, IDisposable
    
   Private _server As New Page13Server
    
   Private nr As Integer = 0
   Private hostName As String = "127.0.0.1"
   Private serverPort As String = "5000"
   Public Property Display As String = "<empty>"
   Public ReadOnly Property Cmd As ICommand = New RelayCommand(AddressOf CmdExec)
   Private Async Sub CmdExec(obj As Object)
     Try
       Dim socket As New StreamSocket()
       Dim serverHost As New HostName(hostName)
       Await socket.ConnectAsync(serverHost, serverPort)
    
       ' Data object for sending
       nr += 1
       Dim d1 As New Page13Data With {.ID = nr, .Info1 = $"Row {nr}", .Info2 = "for response"}
    
       ' Write data to the server.
       Using outp As Stream = socket.OutputStream.AsStreamForWrite()
         Using wrt As New StreamWriter(outp)
           Await wrt.WriteLineAsync(JsonConvert.SerializeObject(d1))
           Await wrt.FlushAsync()
         End Using
       End Using
    
       ' Data object für Empfang
       Dim d2 As Page13Data = Nothing
    
       ' Read data from erver.
       Using inp As Stream = socket.InputStream.AsStreamForRead()
         Using rdr As New StreamReader(inp)
           Dim resp As String = Await rdr.ReadLineAsync()
           'Display = resp
           d2 = JsonConvert.DeserializeObject(Of Page13Data)(resp)
           Display += $"{Environment.NewLine}Received Object from Server ID:{ d2.ID}, Info1: { d2.Info1}, Info2: { d2.Info2}"
         End Using
       End Using
     Catch ex As Exception
       Display = ex.ToString()
     End Try
     OnPropertyChanged(NameOf(Display))
   End Sub
    
   Private Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
   Public Sub OnPropertyChanged(Optional propertyName As String = "")
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
   End Sub
    
 #Region "IDisposable Support"
   Private disposedValue As Boolean ' To detect redundant calls
    
   ' IDisposable
   Protected Overridable Sub Dispose(disposing As Boolean)
     Me._server?.Cancel()
     disposedValue = True
   End Sub
    
   Protected Overrides Sub Finalize()
     Dispose(False)
     MyBase.Finalize()
   End Sub
    
   Public Sub Dispose() Implements IDisposable.Dispose
     Dispose(True)
     GC.SuppressFinalize(Me)
   End Sub
 #End Region
    
 End Class
    
 Public Class Page13Data
   Public Property ID As Integer
   Public Property Info1 As String
   Public Property Info2 As String
 End Class
    
 Friend Class Page13Server
   Private _listeningPort As Integer = 5000
   Private _listenningIPAddress As String = "127.0.0.1"
   Dim source As New CancellationTokenSource()
   Dim token As CancellationToken
    
   Public Sub New()
     token = source.Token
     Call (New TaskFactory(token)).StartNew(AddressOf Start)
   End Sub
    
   Friend Sub Cancel()
     source.Cancel()
   End Sub
    
   Public Async Sub Start()
     Dim ipAddre As IPAddress = IPAddress.Parse(_listenningIPAddress)
     Dim listener As TcpListener = New TcpListener(ipAddre, _listeningPort)
     Try
       listener.Start()
       LogMessage("Server is running")
       LogMessage("Listening on port {_listeningPort}")
       While True
         LogMessage("Waiting for connections...")
         Dim client = Await listener.AcceptTcpClientAsync()
         HandleConnectionAsync(client)
       End While
     Catch ex As Exception
       LogMessage(ex.ToString())
     End Try
   End Sub
    
   Private Async Sub HandleConnectionAsync(client As TcpClient)
     client.LingerState.Enabled = False
     Dim clientInfo As String = client.Client.RemoteEndPoint.ToString()
     LogMessage(String.Format("Got connection request from {0}", clientInfo))
     Try
       Dim d As Page13Data = Nothing
       Using str As NetworkStream = client.GetStream()
         Using wrt As New StreamWriter(str)
           str.ReadTimeout = 600
           Using rdr As New StreamReader(str)
             Dim req As String = Await rdr.ReadLineAsync()
             LogMessage($"Receive from Client:{req}")
             d = GetData(Of Page13Data)(req)
             LogMessage($"Received Object from Client ID:{d.ID}, Info1:{d.Info1}, Info2:{d.Info2}")
             d.Info2 = $"Received from Server for ID {d.ID}"
             Dim resp As String = GetJSon(Of Page13Data)(d)
             Await wrt.WriteLineAsync(resp)
             Await wrt.FlushAsync()
           End Using
         End Using
       End Using
     Catch exp As Exception
       LogMessage(exp.ToString())
     Finally
       LogMessage($"Closing the client connection - {clientInfo}")
       client.Close()
     End Try
   End Sub
   Friend Sub LogMessage(msg As String)
     Debug.WriteLine($"Server:{ msg}")
   End Sub
    
   Private Function GetData(Of T)(json As String) As T
     Return JsonConvert.DeserializeObject(Of T)(json)
   End Function
   Private Function GetJSon(Of T)(obj As T) As String
     Return JsonConvert.SerializeObject(obj)
   End Function
    
 End Class



· 2 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@PeterFleischer-3316 Thank you for the reply. My question was whether there is any limitations on running both the server and client in the same machine. Please see the Note given here https://docs.microsoft.com/en-us/windows/uwp/networking/sockets

0 Votes 0 · ·

To protect the computer from Reflection Attacks, a LoopBack is prevented in the settings and it is recommended to switch off the LoopBackCheck only for test purposes.

0 Votes 0 · ·
pesmith avatar image
1 Vote"
pesmith answered ·

From a UWP app, you cannot connect to "any" other process on the same system. This is a security restriction, enforced by the firewall.

It may appear to work when you are using Visual Studio and debugging your program, but that's because the firewall rules are relaxed while debugging.

Why is "any" in quote marks? Because apparently you ARE allowed to have a socket between two apps in the same package -- but when you do that, note that you may have trouble shipping the resulting app package in the store.

· 3 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@pesmith Thank you. So that means I cannot connect to another non UWP app in the same machine from my UWP app using sockets? Even if it works with VS, it'll not work when I download it from Store. Is that correct? So this restriction is not only for just 2 UWP apps?

0 Votes 0 · ·

@pesmith I just created a sample windows server app and uwp client app and packaged the client uwp app and tested. And still it seems to work in the same machine. Can you please confirm that it'll not work when I submit to Store?

0 Votes 0 · ·

@pesmith By going through other articles/forums looks like I have to create a 'Windows application Packaging project' with a Win32 app and package it and submit to store. So the UWP app can communicate to this Win32 app and it can communicate to the other non UWP app. But from your statement below, do you mean there will be issues when submitting such app to the store? Why is "any" in quote marks? Because apparently you ARE allowed to have a socket between two apps in the same package -- but when you do that, note that you may have trouble shipping the resulting app package in the store. @FayWang-MSFT

0 Votes 0 · ·