Websocket 新帧字节 [英] Websocket new frame byte

查看:30
本文介绍了Websocket 新帧字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在编写一个 Visual Basic 脚本,该脚本在本地机器 ip (127.0.0.1) 和端口 8181 上打开一个 TcpListener.我从 Google Chrome 连接到我的 websocket 服务器(通过 AcceptSocket 方法).从 Chrome 我向服务器发送请求,服务器可以读取它以及所有内容.当我发回消息(如回声)时,我可以第一次发送,但第二次我收到错误:

I am currently writing a Visual Basic script that opens a TcpListener on local machine ip (127.0.0.1) and on port 8181. I connect to my websocket server (via the AcceptSocket method) from Google Chrome. From Chrome i do a send request to the server and the server can read it and everything. When I send the message back (like an echo) I can send it the first time but the second time I get an error:

收到意外的继续帧.

我需要的是一个 CByte,它告诉框架开始一个新的或结束打开的一个(不关闭套接字连接)

What i need is a CByte that tells the frame to start a new one or end the open one (without closing the socket connection)

这是否可以实现,如果可以,解决方案是什么?

Is this achieveable and if so what is the solution?

我用 SendMessage(sck, "test")

这是我的消息发送者的代码:

Here is the code for my message sender:

Sub SendMessage(sck As Socket, message As String)
    Dim rawData = System.Text.Encoding.UTF8.GetBytes(message)
    Dim frameCount = 0
    Dim frame(10) As Byte
    frame(0) = CByte(129)

    If rawData.Length <= 125 Then
        frame(1) = CByte(rawData.Length)
        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 + 1) 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
    sck.Send(reply, reply.Length, 0)
End Sub

更新:

将行 Dim reply(bLength + 1) As Byte 更改为 Dim reply(bLength) As Byte 后,我没有得到连续帧错误,而是得到了一个新的错误:

After changing the line Dim reply(bLength + 1) As Byte to Dim reply(bLength) As Byte i dont get the continuous frame error, but instead i get a new error:

服务器不能屏蔽它发送给客户端的任何帧.

希望这些信息可以指出问题.

Hopefully this information can point to the problem.

更新 2:

下面是整个客户端 Sub 与客户端一起做所有事情.从接受到握手再到消息.

Below is the entire client Sub the does everything with the clients. From accept to handshake to message stuff.

Private Sub clientStarter(ByVal sck As Socket)
    Dim netStream As New NetworkStream(sck)
    Dim netReader As New IO.StreamReader(netStream)
    Dim netWriter As New IO.StreamWriter(netStream)

    Dim key As String = ""

    Console.WriteLine("Accept new connection ...")

    '' Reading handshake message
    While (True)
        Dim line As String = netReader.ReadLine()
        If line.Length = 0 Then
            Exit While
        End If

        If (line.StartsWith("Sec-WebSocket-Key: ")) Then
            key = line.Split(":")(1).Trim()
        End If

        Console.WriteLine("Data: " & line)
    End While

    '' Calculate accept-key
    key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
    key = getSHA1Hash(key)

    '' Response handshake message
    Dim response As String
    response = "HTTP/1.1 101 Switching Protocols" & vbCrLf
    response &= "Upgrade: websocket" & vbCrLf
    response &= "Connection: Upgrade" & vbCrLf
    response &= "Sec-WebSocket-Accept: " & key & vbCrLf & vbCrLf
    netWriter.Write(response)
    netWriter.Flush()
    Dim dataSent As [Byte]() = Nothing
    Dim dataRecieved(1024) As [Byte]
    Dim bytes As Int32
    Console.WriteLine(dataRecieved)
    Dim message As String = Nothing
    While (True)
        If (sck.Connected = False) Then
            Exit While
        End If
        bytes = sck.Receive(dataRecieved, dataRecieved.Length, 0)
        'Console.WriteLine(bytes)
        While (bytes > 0)
            Console.WriteLine("recieved Data")
            message = System.Text.Encoding.UTF8.GetString(dataRecieved, 0, bytes)
            Console.WriteLine(bytes)
            bytes = 0
            If (bytes = 0) Then
                Console.WriteLine("test")
                Console.WriteLine(message)

                dataSent = System.Text.Encoding.UTF8.GetBytes(message, 0, bytes)
                SendMessage(sck, "test")
                message = Nothing
            End If
        End While
    End While
End Sub

更新 3(解决方案):

Update 3 (solution):

我已经解决了我的问题.通过将 frame(1) = CByte(rawData.Length) 更改为 frame(1) = CByte(rawData.Length + 1) 它合并了结尾 0 字节,现在消息的适当长度是正确的,并且消除了我的掩蔽问题.我猜消息字节的结尾应该包含在消息长度中.

I have figured out my problem. By changing frame(1) = CByte(rawData.Length) to frame(1) = CByte(rawData.Length + 1) it incorperates the end 0 byte and now the proper length of the message is correct and rids me of my masking problem. I guess the end of the message byte is supposed to be included in the message length.

推荐答案

看起来您在消息的末尾包含了一个额外的字节.该不该行

It looks like you're including an extra byte at the end of your message. Shouldn't the line

Dim reply(bLength + 1) As Byte

改为

Dim reply(bLength) As Byte

相反?您在消息中只需要操作码 + 长度 (frameCount) + 消息 (rawData.Length).websocket 客户端会将这些字节读取为完整、有效的消息.然后它将读取您消息中的剩余字节作为新消息的开始,从而有效地破坏您实际发送的下一条消息.

instead? All you need in your message is opcode + length (frameCount) + message (rawData.Length). A websocket client will read these bytes as a full, valid message. It will then read the remaining byte from your message as the start of a new message, effectively corrupting the next message you actually send.

这篇关于Websocket 新帧字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆