0
votes

I try to create and app by Websocket. I did handshake good when i try to send any message to client client close the connection as WebSocket Error: Network Error 12152

I guess problem is encoding data. I use a script founded on Websocket new frame byte

but its not working good. i hope you can help me This is my code:

Dim rawData = System.Text.Encoding.UTF8.GetBytes("hello")
                Dim frameCount = 0
                Dim frame(10) As Byte
                frame(0) = CByte(129)

                If rawData.Length <= 125 Then
                    frame(1) = CByte(rawData.Length + 1)
                    frameCount = 2
                ElseIf rawData.Length >= 126 AndAlso rawData.Length <= 65535 Then
                    frame(1) = CByte(126)
                    Dim len = CByte(rawData.Length)
                    frame(2) = CByte(((len >> 8) & CByte(255)))
                    frame(3) = CByte((len & CByte(255)))
                    frameCount = 4
                Else
                    frame(1) = CByte(127)
                    Dim len = CByte(rawData.Length)
                    frame(2) = CByte(((len >> 56) & CByte(255)))
                    frame(3) = CByte(((len >> 48) & CByte(255)))
                    frame(4) = CByte(((len >> 40) & CByte(255)))
                    frame(5) = CByte(((len >> 32) & CByte(255)))
                    frame(6) = CByte(((len >> 24) & CByte(255)))
                    frame(7) = CByte(((len >> 16) & CByte(255)))
                    frame(8) = CByte(((len >> 8) & CByte(255)))
                    frame(9) = CByte((len & CByte(255)))
                    frameCount = 10
                End If
                Dim bLength = frameCount + rawData.Length
                'Console.WriteLine(frameCount)
                'Console.WriteLine(rawData.Length)
                Dim reply(bLength) As Byte

                Dim bLim = 0
                For i = 0 To frameCount - 1
                    'Console.WriteLine(bLim)
                    reply(bLim) = frame(i)
                    bLim += 1
                Next

                For i = 0 To rawData.Length - 1
                    'Console.WriteLine(bLim)
                    reply(bLim) = rawData(i)
                    bLim += 1
                Next
                For i = 0 To reply.Length - 1
                    'Console.WriteLine("Byte: " & reply(i))
                    'Console.WriteLine("Char: " & CByte(reply(i)))
                Next

                Dim asd As String = Encoding.UTF8.GetString(reply)
                Console.WriteLine(asd)
                pv_streamwriter.WriteLine(asd)
                pv_streamwriter.Flush()
1

1 Answers

0
votes

Thanks for using my code. Definately cool to see.

Anyways, I myself figured out this annoying problem with the send function.

According to RFC6455 You are required To mask the sent message when sending a message to the server but not required to mask it when sending the message from server to client. Now, having said that, I have changed that function to include masking from client to server. I will be removing my specific mask code because I dont want it on the net. Hope this helps.

A note on creating a secure mask. RFC6455 mentions RFC4086:

The masking key is a 32-bit value chosen at random by the client.
   When preparing a masked frame, the client MUST pick a fresh masking
   key from the set of allowed 32-bit values.  The masking key needs to
   be unpredictable; thus, the masking key MUST be derived from a strong
   source of entropy, and the masking key for a given frame MUST NOT
   make it simple for a server/proxy to predict the masking key for a
   subsequent frame.  The unpredictability of the masking key is
   essential to prevent authors of malicious applications from selecting
   the bytes that appear on the wire.  [RFC 4086][RFC4086] discusses what
   entails a suitable source of entropy for security-sensitive
   applications.

Honestly I just wanted to get it working before I followed that document so i used a combination of Rnd(), modulus, and some other stuff to make it hard to decode.

Sub SendMessage2(ByVal socket As Socket, ByVal message As String, ByVal len As Integer)
    Dim frameCount As Integer
    Dim len16 As UInt16
    Dim reply(len + 8) As [Byte]
    Dim frame(10) As [Byte]
    Dim maskingBytes(4) As [Byte]

    frame(0) = CByte(&H81)

    If (len <= 125) Then
        frame(1) = CByte(len + 128)
        frameCount = 2
    ElseIf (len >= 126 AndAlso len <= 65535) Then
        frame(1) = CByte(126 + 128)
        len16 = Convert.ToUInt16(len)
        frame(2) = CByte(BitConverter.GetBytes(len16).GetValue(0))
        frame(3) = CByte(BitConverter.GetBytes(len16).GetValue(1))
        frameCount = 4
    Else
        frame(1) = CByte(127 + 128)
        'Odds are we are not ever going to get here. but here is some code
        'frame(2) = CByte(((len >> 56) And CByte(255)))
        'frame(3) = CByte(((len >> 48) And CByte(255)))
        'frame(4) = CByte(((len >> 40) And CByte(255)))
        'frame(5) = CByte(((len >> 32) And CByte(255)))
        'frame(6) = CByte(((len >> 24) And CByte(255)))
        'frame(7) = CByte(((len >> 16) And CByte(255)))
        'frame(8) = CByte(((len >> 8) And CByte(255)))
        'frame(9) = CByte((len) And CByte(255))
        frameCount = 10
    End If

    For i As Integer = 0 To frameCount - 1
        reply(i) = Convert.ToByte(frame(i))
    Next

    For i As Integer = 0 To 3
        Randomize()
        maskingBytes(i) = 0'This is where you need to create your own masking byte
        reply(frameCount + i) = maskingBytes(i)
    Next

    For i As Integer = 0 To len
        If (Not i = len) Then
            reply(frameCount + i + 4) = Convert.ToByte(message.Chars(i)) Xor maskingBytes(i Mod 4)
        Else
            reply(frameCount + i + 4) = CByte(0) Xor maskingBytes(i Mod 4)
        End If
    Next


    If (socket.Send(reply) <= 0) Then
        Console.WriteLine("WE ARE NOT WRITING!!")
    End If

End Sub