phreak87
Goto Top

VB.Net asynchrone Clientssockets

Hallo,

ich möchte mir einen WebSocket-Client bauen und habe dabei folgendes Problem:

Wenn die Verbindung zum Server aufgebaut wurde rufe ich die Sub ReceiveSingle auf.
Diese wartet mit BeginReceive auf eine eingehende Nachricht (z.B. Ping) vom Server, empfängt
die Bytes und gibt sie aus.
Anschließend rufe ich die Sub wieder auf. BeginReceive löst sofort den AsyncCallback auf und es wird
1 Byte =0 gelesen und zurückgegeben.
Durch die schleife geht es dann endlos mit 1 Byte lesen weiter ... bis der Server oder Client die Verbindung
trennt.
Was kann ich tun damit BeginReceive bei weiteren Aufrufen wieder auf eine "echte, gefüllte" Nachricht wartet?
Bei Websockets kann ich die Verbinung auch schlecht nach dem Empfang unterbrechen face-sad


Sub ConnectToEndpoint () 
... Verbindung zu Remote Endpoint ...
... Verbindung aufgebaut ...

Do
     Dim B() as byte = ReceiveSingle(SOC)
     Console.writeline (getstring(b))
Loop
End Sub
Function ReceiveSingle (socket) as Byte()
        Dim bytes(1024) As Byte
        If Socket.Connected = False Then Return Nothing
        Dim Received As New Threading.AutoResetEvent(False)
        Try
            Socket.BeginReceive(bytes, 0, 0, SocketFlags.Peek,
                New AsyncCallback(
                    Sub(ac)
                        Dim i As Integer = Socket.EndReceive(ac)
                        Socket.Receive(bytes, 0, Socket.Available - 1, SocketFlags.None)
                        Received.Set()
                    End Sub
            ), Nothing)
        Catch ex As Exception
            Return Nothing
        End Try
        Received.WaitOne()
        Return bytes
end sub

Content-Key: 369811

Url: https://administrator.de/contentid/369811

Printed on: April 20, 2024 at 00:04 o'clock

Member: emeriks
emeriks Mar 31, 2018 at 15:48:38 (UTC)
Goto Top
Hi,
erstmal: "Sub" und "Return" passen nicht zusammen. Vielleicht solltest Du hier den realen Code posten?

Dann:
Der Client wartet auf eine Nachricht vom Server? Sollte es nicht umgedreht sein? Bzw. der Client wartet auf eine Antwort des Servers, nachdem er eine Anfrage gestellt hat?

Ich würde das so lösen, dass ich auch am Client einen Listener starte und dem Server mitteile, dass das so ist und an welchem Port. Dann sendet der Server an diesen Listener und der Client kann reagieren. Der Client fungiert also in diesem Punkt als Server und umgekehrt. Das wäre m.E. auch viel übersichtlicher im Code. Aber vielleicht bin ich da Old School?

Den Server hast Du auch selbst geschrieben?

E.
Member: Phreak87
Phreak87 Mar 31, 2018 at 17:56:43 (UTC)
Goto Top
Hallo,

das mit der Sub stimmt wohl. Der Rest ist 1:1 aus meinem Code. Hab es hier ausgebessert.

Natürlich hast du recht dass der Client in der Regel an den Server sendet und eine Antwort bekommt.
Bei Websockets ist es jedoch wie bei einem echten Chat, jeder kann schreiben wann er will und so oft
er will, mit und ohne Antwort der Gegenstelle.

In meinem Fall warte ich nur so lange bis der Server (ws://echo.websocket.org) einen Ping sendet.
Ich sende danach einen Pong und lausche wieder ... danach kommt nur noch mist und er
wartet nicht mehr (z.B. auf erneuten Ping) sondern löst das Event direkt mit 0 Bytes aus.

wenn ich das ganze in Chrome auf der Testseite teste funktioniert es genau so wie es soll (ohne
0-Byte Messages.). Im Debug sieht man die weiteren Ping/Pong Nachrichten alle x Sec.

Nach dem mitschneiden der Chrome-Kommunikation per Wireshark habe ich bemerkt dass beim senden
des Pong das Mask Bit gesetzt ist und eine Mask nach dem 2. Byte angehängt ist. vielleicht ist dass der
Schlüssel. Vielleicht ist die Kommunikation schon beendet und er empfängt deshalb nur Mist. Was mich
daran wundert ist dass das Property Connected in dem Fall immer noch auf True steht -_-
Member: Phreak87
Phreak87 Mar 31, 2018 at 18:22:39 (UTC)
Goto Top
Problem gelöst ...

der Pong des Clients muss! bei Websockets das Mask Bit gesetzt haben und Bytes
3-6 müssen die Mask sein. Vermute um damit ein Proxy-Caching zu umgehen.
die Pong Bits sind dann {138 (FIN(128) + Pong(10),128(MASK),0-255,0-255,0-255,0-255).
Wenn der Pong falsch gesendet wird bleibt der Socket-State auf Connected und führt
zu dem von mir genannten Fehlverhalten.