none
Windows Universal Network zu VB .Net RRS feed

  • Frage

  • Hallo

    Ich wollte mal fragen ob schon jemand versucht hat eine Netzwerkverbindung zwischen einer Universal App die mit Windows.Networking.Sockets arbeitet und einem Windows Programm oder Dienst der mit System.Net arbeitet herzustellen.

    Habe das heute mal versucht und die Verbindung wird auch aufgebaut allerdings kann ich keine Daten senden.

    Interessanter weise bekomme ich wenn ich von der App zum Programm verbinde zwar eine Verbindung aber es werden keine Daten übertragen. Wenn ich die App schließe komme die Daten aber manchmal an.

    Hier hab ich mal den Code von meinem Klassischen Programm:

    Imports System.Net.Sockets
    Imports System.IO
    Imports System.Net
    Imports System.Xml
    
     Module Module1
         Private server As TcpListener
         Private client As New TcpClient
         Private ipendpoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 8000)
         Private list As New List(Of Connection)
         Private serverlist As New List(Of Connection)
    
         Private Structure Connection
             Dim stream As NetworkStream
             Dim streamw As StreamWriter
             Dim streamr As StreamReader
             Dim nick As String
             Dim type As String
             Dim pcname As String
         End Structure
    
         Sub Main()
             Console.WriteLine("Der Server läuft!")
             server = New TcpListener(ipendpoint)
             server.Start()
    
             While True '
                 client = server.AcceptTcpClient
    
                 Dim c As New Connection
                 c.stream = client.GetStream
                 c.streamr = New StreamReader(c.stream)
                 c.streamw = New StreamWriter(c.stream)
                 Dim x As String
                 Dim y As String = ""
                 Dim z As String = ""
                 Dim type As String = ""
                 Dim xml As New XmlDocument
                 x = c.streamr.ReadLine
                 Console.WriteLine(x)
             End While
         End Sub
    
    End Module

    Und hier mal den Code meiner App in der ich zum Test einfach mal das Beispiel von git etwas angepasst habe.

    Imports Windows.ApplicationModel.Core
    Imports Windows.Networking.Sockets
    Imports Windows.Storage.Streams
    Imports Windows.UI.Core
    Imports Windows.UI.Xaml
    Imports Windows.UI.Xaml.Controls
    Imports Windows.UI.Xaml.Navigation
    ''' <summary>
    ''' Eine leere Seite, die eigenständig verwendet werden kann oder auf die innerhalb eines Rahmens navigiert werden kann.
    ''' </summary>
    Public NotInheritable Class MainPage
         Inherits Page
    
         Private Async Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
             If CoreApplication.Properties.ContainsKey("listener") Then
                 textBox.Text = "Wurde bereits aktiviert"
                 Exit Sub
             End If
    
             Dim listener As New StreamSocketListener()
             AddHandler listener.ConnectionReceived, AddressOf OnConnection
             CoreApplication.Properties.Add("listener", listener)
    
             Try
                 Await listener.BindServiceNameAsync("2222")
                 textBox.Text = "Listen"
             Catch exception As Exception
                 If SocketError.GetStatus(exception.HResult) = SocketErrorStatus.Unknown Then
                     Throw
                 End If
    
                 textBox.Text = "Start listening failed with error: " & exception.Message
             End Try
         End Sub
    
         Private Async Sub OnConnection(sender As StreamSocketListener, args As StreamSocketListenerConnectionReceivedEventArgs)
             Dim reader As New DataReader(args.Socket.InputStream)
             Try
                 While True
                     Dim sizeFieldCount As UInteger = Await reader.LoadAsync(4)
    
                     If sizeFieldCount <> System.Runtime.InteropServices.Marshal.SizeOf(GetType(UInteger)) Then.
                         Exit Sub
                     End If
    
                     Dim stringLength As UInteger = reader.ReadUInt32()
                     Dim actualStringLength As UInteger = Await reader.LoadAsync(stringLength)
                     If stringLength <> actualStringLength Then
                         Exit Sub
                     End If
    
                     NotifyUserFromAsyncThread(String.Format("Receive data: ""{0}""", reader.ReadString(actualStringLength)))
                 End While
             Catch exception As Exception
                 If SocketError.GetStatus(exception.HResult) = SocketErrorStatus.Unknown Then
                     Throw
                 End If
    
                 NotifyUserFromAsyncThread("Read stream failed with error: " & exception.Message)
             End Try
         End Sub
    
         Private Async Sub NotifyUserFromAsyncThread(strMessage As String)
             Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub()
                                                                          textBox1.Text = strMessage
                                                                      End Sub)
         End Sub
    
         Private Async Sub button1_Click(sender As Object, e As RoutedEventArgs) Handles button1.Click
             If CoreApplication.Properties.ContainsKey("clientSocket") Then
                 textBox.Text = "This step has already been executed. Please move to the next one."
                 Return
             End If
    
             Dim socket As New StreamSocket()
             Dim hostname As New Windows.Networking.HostName("localhost")
             CoreApplication.Properties.Add("clientSocket", socket)
    
             Try
                 Await socket.ConnectAsync(hostname, "8000")
                 textBox.Text = "Connected to the server"
                 CoreApplication.Properties.Add("connected", Nothing)
             Catch exception As Exception
                 If SocketError.GetStatus(exception.HResult) = SocketErrorStatus.Unknown Then
                     Throw
                 End If
                 textBox.Text = "Connect failed with error: " & exception.Message
             End Try
         End Sub
    
         Private Async Sub button2_Click(sender As Object, e As RoutedEventArgs) Handles button2.Click
             If Not CoreApplication.Properties.ContainsKey("connected") Then
                 textBox.Text = "Please run previous steps before doing this one."
                 Return
             End If
    
             Dim outValue As Object = Nothing
             Dim socket As StreamSocket
             If Not CoreApplication.Properties.TryGetValue("clientSocket", outValue) Then
                 textBox.Text = "Please run previous steps before doing this one."
                 Return
             End If
    
             socket = DirectCast(outValue, StreamSocket)
             Dim writer As DataWriter
             If Not CoreApplication.Properties.TryGetValue("clientDataWriter", outValue) Then
                 writer = New DataWriter(socket.OutputStream)
                 CoreApplication.Properties.Add("clientDataWriter", writer)
             Else
                 writer = DirectCast(outValue, DataWriter)
             End If
             Dim stringToSend As String = "Test"
             writer.WriteUInt32(writer.MeasureString(stringToSend))
             writer.WriteString(stringToSend)
    
             Try
                 Await writer.StoreAsync()
                 textBox.Text = """" & stringToSend & """ sent successfully."
             Catch exception As Exception
                 ' If this is an unknown status it means that the error if fatal and retry will likely fail.
                 If SocketError.GetStatus(exception.HResult) = SocketErrorStatus.Unknown Then
                     Throw
                 End If
    
                 textBox.Text = "Send failed with error: " & exception.Message
             End Try
         End Sub
    
    End Class
       

    Ich hoffe jemand hat ne Idee was angepasst werden muss damit ich mehrere Programm Typen über Netzwerk miteinander verbinden kann.

    Danke schon mal für die Antworten

    Sonntag, 6. September 2015 18:01

Antworten

Alle Antworten

  • Hallo Tony R88,

    Würdest Du versuchen, bei ConnectAsync, StoreAsync und LoadAsync Haltepunkte zu setzen? Werden dann Daten empfangen? Sieh Dir folgenden Thread an:
    StreamSocket, DataWriter.StoreAsync(), DataReader.LoadAsync() -- Asynchronous problems

    Gruß,
    Dimitar


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Montag, 7. September 2015 17:58
    Administrator
  • Hi

    Also der Connect läuft mit und ohne Haltpunkt sauber durch. Der Store Befehl auch und nen Read hab ich bisher noch nicht drin da ich noch versuche die Daten zu verschicken.

    Danke für den Thread der ist ganz hilfreich aber ich hab ja alles schon mit async und await drin.

    Gruß

    Tony

    Montag, 7. September 2015 21:06
  • Hallo,

    Du erwartest beim Server eine Zeile, die mit "\r\n" abgeschlossen seinen soll ( Beschreibung).

    x = c.streamr.ReadLine

    Und hier schickst Du nur UInt und String "Text"

    Dim stringToSend As String = "Test"
             writer.WriteUInt32(writer.MeasureString(stringToSend))
             writer.WriteString(stringToSend)

    Richtig wäre:

    Dim stringToSend As String = "Test\r\n"
             writer.WriteUInt32(writer.MeasureString(stringToSend))
    writer.WriteString(stringToSend)

    Grüße


    • Bearbeitet Iso7 Dienstag, 8. September 2015 08:12
    Dienstag, 8. September 2015 08:11
  • Hallo

    Danke für den Tipp.

    Ich hab das jetzt grade mal versucht.

    Das ist das selbe verhalten wie vorher. Er kann keinen Stream lesen und wenn ich die App schließe geht es ab und zu. Aber normalerweise bekomme ich den Fehler: {"Von der Übertragungsverbindung können keine Daten gelesen werden: Eine vorhandene Verbindung wurde vom Remotehost geschlossen."}

    Vielleicht sagt das ja einem etwas mehr. Ich verstehe nämlich nicht warum er sagt das keine Daten gelesen werden konnten weil es waren ja welche drin.

    Gruß

    Tony

    Mittwoch, 9. September 2015 15:54
  • Hallo Tony,

    ich würde den DataWriter immer mit dem OutputStream von aktuellen Socket erzeugen. Es gibt eine Gefahr, dass Du DataWriter von alten Socket in deiner Variante verwendest.

    also

     If Not CoreApplication.Properties.TryGetValue("clientDataWriter", outValue) Then
                 writer = New DataWriter(socket.OutputStream)
                 CoreApplication.Properties.Add("clientDataWriter", writer)
             Else
                 writer = DirectCast(outValue, DataWriter)
             End If

    ersetzen mit:

    writer = New DataWriter(socket.OutputStream)

    Nach dem StoreAsync auch FlushAsync und DetachStream aufrufen.

    Dim stringToSend As String = "Test"
             writer.WriteUInt32(writer.MeasureString(stringToSend))
             writer.WriteString(stringToSend)
    
             Try
                 Await writer.StoreAsync()
                 Await writer.FlushAsync()
                 
                 writer.DetachStream()
     
                 textBox.Text = """" & stringToSend & """ sent successfully."
             Catch exception As Exception
                 ' If this is an unknown status it means that the error if fatal and retry will likely fail.
                 If SocketError.GetStatus(exception.HResult) = SocketErrorStatus.Unknown Then
                     Throw
                 End If
    
                 textBox.Text = "Send failed with error: " & exception.Message
             End Try

    Grüße

    Donnerstag, 10. September 2015 11:42
  • Hallo

    Danke erst mal für den Tipp.

    Leider hat es nicht geklappt. Hab allerdings was gefunden. nämlich wenn ich einen Read statt readline mache bekomme ich die Daten muss aber das ende vorher am begin des Streams lesen was mir noch etwas Probleme macht.

    Hab bisher nur leider noch keinen weg gefunden um die 4 gelesenen Bytes in einen Uint wert zu wandeln.

    Wenn noch jemand ne Idee hat bin ich sehr dankbar. Auch wenn es noch nen ganz anderen weg gibt natürlich.

    Gruß

    Tony

    Samstag, 12. September 2015 20:32
  • Hallo,

    BitConverter kann Byte Arrray in Uint konvertieren.

    Grüße

    Samstag, 12. September 2015 21:31
  • Hallo

    Auf bitconverter bin ich auch gekommen nur leider ist das Ergebnis vollkommen falsch.

    Es kommen irgendwas um die 430000 raus wo 287 raus kommen sollten.

    Gruß

    Tony

    Sonntag, 13. September 2015 11:40
  • Hallo Tony,

    das sieht nach Big/Little-Endian  Problem aus. Du kannst die Byte- Folge mit Array.Reverse(..) umdrehen.

    Grüße 

    Sonntag, 13. September 2015 12:25
  • Hi

    Sorry das es so lange gedauert hat aber ich bin jetzt endlich mal wieder zum Testen gekommen.

    Du hast komplett recht gehabt. Das Array war einfach gedreht.

    Danke noch mal für die Antwort.

    Sonntag, 18. Oktober 2015 18:04