【问题标题】:websocket stop responding after handshake握手后websocket停止响应
【发布时间】:2018-09-20 14:38:15
【问题描述】:

我正在构建一个带有简单套接字的 websocket 客户端 (vb.net)。 我这样做是为了在嵌入式项目(cc3220)上开始之前更好地理解它。

看来我通过握手就好了,在接收到一个文本帧后,数据停止接收。

websocket 服务器是 .net 核心 Azure 项目作为 echo。适用于具有多个连接的简单 websocket 客户端 chrome 扩展。

这是我的 VB.NET 应用程序的日志,也许有人能发现问题:

--- Sending via socket-- 
GET http://xxxxxxxx.azurewebsites.net/xxxxxxx HTTP/1.1
Host: xxxxxxxxxx.azurewebsites.net
Connection: Upgrade
Upgrade: WebSocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: gnuE6HbBVfsHzYVNLdxxbQ==


--- New pack received--- 
total bytes:206
72,84,84,80,47,49,46,49,32,49,48,49,32,83,119,105,116,99,104,105,110,103,32,80,114,111,116,111,99,111,108,115,13,10,85,112,103,114,97,100,101,58,32,119,101,98,115,111,99,107,101,116,13,10,83,101,114,118,101,114,58,32,75,101,115,116,114,101,108,13,10,83,101,99,45,87,101,98,83,111,99,107,101,116,45,65,99,99,101,112,116,58,32,84,101,70,54,79,103,112,48,109,79,106,118,102,105,99,70,82,116,90,48,107,105,52,114,83,49,103,61,13,10,88,45,80,111,119,101,114,101,100,45,66,121,58,32,65,83,80,46,78,69,84,13,10,67,111,110,110,101,99,116,105,111,110,58,32,85,112,103,114,97,100,101,13,10,68,97,116,101,58,32,84,117,101,44,32,49,48,32,65,112,114,32,50,48,49,56,32,50,48,58,51,56,58,53,54,32,71,77,84,13,10,13,10,0,
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Server: Kestrel
Sec-WebSocket-Accept: TeF6Ogp0mOjvficFRtZ0ki4rS1g=
X-Powered-By: ASP.NET
Connection: Upgrade
Date: Tue, 10 Apr 2018 20:38:56 GMT


--- New pack receive--- 
total bytes:42
129,24,119,101,108,99,111,109,101,32,104,111,119,32,100,111,32,121,111,117,32,100,111,63,13,10,129,14,110,101,119,32,99,111,110,110,101,99,116,105,111,110,32,
welcome how do you do?
new connection 
Length: 24 op_code: 1(string data)

-- sending data (string 123) via socket, here there is no respond, the server should echo this ----
Sending string: 123
Sending bytes: 129,3,49,50,51,
Sending string: 123
Sending bytes: 129,3,49,50,51,


--- even when sending data via another websocket client app, the data is not received here, but it does to the third websocket client app ---

Vb代码:

Public Class SocketObject
    Public socket As Socket = Nothing
    Public Const BUFFER_SIZE As Integer = 1024
    Public buffer(BUFFER_SIZE) As Byte
End Class 'StateObject

Dim sock As New SocketObject()

Private Sub printbytes(ByVal bytes() As Byte, ByVal size As Int16)
    Dim i As Integer = 0
    Dim a As String = vbCrLf + "--- New pack receive--- " + vbCrLf + "total bytes:" + size.ToString() + vbCrLf
    Dim b As String = ""
    For i = 0 To size
        a += bytes(i).ToString() + ","
        b += Chr(bytes(i))
    Next

    Dim c As String = ""

    If (bytes(0) >= &H0) And (bytes(0) <= &H7F) Then
        c = "(0x00 to 0x7F) --> Data... --> 0xFF "
    Else
        c = "(0x80 to 0xFF) --> Length --> Data..."
        c += " Length: " + bytes(1).ToString()

        Dim op_code As Byte = bytes(0) And &HF
        c += " op_code: " + op_code.ToString()

        Select Case op_code
            Case 9
                c += "(ping) response - Pong"
                Dim ascii As Encoding = Encoding.UTF8
                Dim request As String = "  Pong"
                Dim bytesSent As [Byte]() = ascii.GetBytes(request)

                bytesSent(0) = &H8A
                bytesSent(1) = 4

                ' Send request to the server.
                sock.socket.Send(bytesSent, bytesSent.Length, 0)
            Case 10
                c += "(pong)"
            Case 1
                c += "(string data)"
            Case 2
                c += "(binary data)"
            Case 8
                c += "(connection close) - response and close"

                Dim ascii As Encoding = Encoding.UTF8
                Dim request As String = " "
                Dim bytesSent As [Byte]() = ascii.GetBytes(request)

                bytesSent(0) = &H8

                ' Send request to the server.
                sock.socket.Send(bytesSent, bytesSent.Length, 0)
            Case Else
                c += "(unknown!!)"
        End Select
    End If

    Me.Dispatcher.Invoke(Windows.Threading.DispatcherPriority.Background, New Delegate_LableAddText(AddressOf LableAddText), a + vbCrLf + b + vbCrLf + c + vbCrLf + vbCrLf)
End Sub


Public Sub Read_Callback(ar As IAsyncResult)
    Dim so As SocketObject = CType(ar.AsyncState, SocketObject)
    Dim s As Socket = so.socket
    Try
        Dim read As Integer = s.EndReceive(ar)

        If read > 0 Then
            Dim frameCount = 2
            Dim bytes As Byte() = so.buffer

            printbytes(bytes, read)
        End If

        If (s.Connected = True) Then
            s.BeginReceive(so.buffer, 0, SocketObject.BUFFER_SIZE, 0, New AsyncCallback(AddressOf Read_Callback), so)
        Else
            Me.Dispatcher.Invoke(Windows.Threading.DispatcherPriority.Background, New Delegate_LableAddText(AddressOf LableAddText), "-close-")
        End If
    Catch

    End Try
End Sub


Public Delegate Sub Delegate_LableAddText(ByVal str As String)
''' <summary>
''' Check the received data and see if there is command from the device to check
''' </summary>
''' <param name="str"></param>
Public Sub LableAddText(ByVal str As String)
    LblSock.Text += str
End Sub

Private Sub Button3_Click(sender As Object, e As RoutedEventArgs)
    sock.socket.Close()
End Sub

Private Function random_sc_key() As String
    Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    Dim r As New Random
    Dim sb As New StringBuilder
    For i As Integer = 0 To "gnuE6HbBVfsHzYVNLdxxbQ==".Length
        Dim idx As Integer = r.Next(0, 35)
        sb.Append(s.Substring(idx, 1))
    Next
    Dim a As String = sb.ToString()
    Return "gnuE6HbBVfsHzYVNLdxxbQ=="
End Function

Private Sub BtnConnect_Click(sender As Object, e As RoutedEventArgs)
    LblSock.Text = ""
    'Set up variables and String to write to the server.
    Dim ascii As Encoding = Encoding.UTF8
    Dim request As String = "GET http://xxxxxxxxx.azurewebsites.net/xxxxxxxxx HTTP/1.1" + ControlChars.Cr + ControlChars.Lf + "Host: xxxxxxxxx.azurewebsites.net" + ControlChars.Cr + ControlChars.Lf + "Connection: Upgrade" + ControlChars.Cr + ControlChars.Lf + "Upgrade: WebSocket" + ControlChars.Cr + ControlChars.Lf + "Sec-WebSocket-Version: 13" + ControlChars.Cr + ControlChars.Lf + "Sec-WebSocket-Key: " + random_sc_key() + vbCrLf + vbCrLf
    Dim bytesSent As [Byte]() = ascii.GetBytes(request)
    Dim bytesReceived(255) As [Byte]

    Dim hostEntry As IPHostEntry = Nothing

    ' Get host related information.
    hostEntry = Dns.GetHostEntry("xxxxxxxxx.azurewebsites.net")

    Dim address As IPAddress

    For Each address In hostEntry.AddressList
        Dim endPoint As New IPEndPoint(address, 80)
        Dim tempSocket As New Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
        tempSocket.Connect(endPoint)
        If tempSocket.Connected Then
            sock.socket = tempSocket
            Exit For
        End If
    Next address

    If sock.socket Is Nothing Then
        MessageBox.Show("Connection failed")
        Exit Sub
    End If

    LblSock.Text += "Sending: " + request

    ' Send request to the server.
    sock.socket.Send(bytesSent, bytesSent.Length, 0)

    LblSock.Text += "BeginReceive" + vbCrLf

    sock.socket.BeginReceive(sock.buffer, 0, SocketObject.BUFFER_SIZE, 0, New AsyncCallback(AddressOf Read_Callback), sock)
End Sub

Private Sub BtnSendString1_Click(sender As Object, e As RoutedEventArgs)
    If (sock.socket.Connected = False) Then
        LblSock.Text += vbCrLf + "connection closed" + vbCrLf
        Exit Sub
    End If

    Dim request As String = txtsock.Text
    request = "11" & request

    Dim ascii As Encoding = Encoding.UTF8
    Dim bytesSent As Byte() = ascii.GetBytes(request)

    bytesSent(0) = &H81
    bytesSent(1) = txtsock.Text.Length

    LblSock.Text += vbCrLf + "Sending string: " + txtsock.Text
    LblSock.Text += vbCrLf + "Sending bytes: "

    Dim i As Int16
    For i = 0 To bytesSent.Length - 1
        LblSock.Text += bytesSent(i).ToString() + ","
    Next

    sock.socket.Send(bytesSent)
End Sub

Private Sub BtnCloseSock_Click(sender As Object, e As RoutedEventArgs)
    If (sock.socket.Connected = False) Then
        LblSock.Text += vbCrLf + "connection closed" + vbCrLf
        Exit Sub
    End If

    Dim request As String = txtsock.Text
    request = "1" & request & "1"

    Dim ascii As Encoding = Encoding.UTF8
    Dim bytesSent As Byte() = ascii.GetBytes(request)

    bytesSent(0) = 0
    'bytesSent(1) = txtsock.Text.Length
    bytesSent(bytesSent.Length - 1) = &HFF

    sock.socket.Send(bytesSent)
End Sub

【问题讨论】:

  • 没有代码,很难帮助你......我预感我会说客户端没有正确编码 WebSocket 数据。您确定要根据客户端上的 WebSocket 协议对数据进行编码吗?您的客户是否正确屏蔽了数据?您是否将掩码附加在编码数据的头部(在数据包的头部之后和数据之前)?
  • 附加代码,字符串是 UTF-8 编码的,我还添加了发送到服务器和从服务器发送的字节,它看起来类似于协议。但我仍然想念一些东西。
  • 此行:bytesSent(1) = txtsock.Text.Length 仅对txtsock.Text.Length &lt; 127 有效。客户端似乎也没有屏蔽消息(客户端必须屏蔽,服务器不能屏蔽,存在编码差异)......再说一次,我对 VB.NET 没有任何好处。考虑将语言标签添加到您的问题中,也许您会得到更多的输入。
  • 关于帧(

标签: websocket


【解决方案1】:

感谢 Myst 指出 MASK 问题。 这是从客户端执行简单文本传输到服务器的固定代码:

Private Sub BtnSendString1_Click(sender As Object, e As RoutedEventArgs)
    If (sock.socket.Connected = False) Then
        LblSock.Text += vbCrLf + "connection closed" + vbCrLf
        Exit Sub
    End If

    Dim rand As Random = New Random()
    Dim masking_key(4) As Byte
    Dim i As Integer


    masking_key(0) = Convert.ToByte(rand.Next(0, 250))
    masking_key(1) = Convert.ToByte(rand.Next(0, 250))
    masking_key(2) = Convert.ToByte(rand.Next(0, 250))
    masking_key(3) = Convert.ToByte(rand.Next(0, 250))

    Dim request As String = txtsock.Text
    If (txtsock.Text.Length <= 125) Then
        request = "112222" & request

        Dim ascii As Encoding = Encoding.UTF8
        Dim bytesSent As Byte() = ascii.GetBytes(request)

        bytesSent(0) = &H80 Or 1
        bytesSent(1) = txtsock.Text.Length Or &H80
        bytesSent(2) = masking_key(0)
        bytesSent(3) = masking_key(1)
        bytesSent(4) = masking_key(2)
        bytesSent(5) = masking_key(3)


        Dim s As Integer = 0
        For i = 6 To bytesSent.Length - 1
            bytesSent(i) = bytesSent(i) Xor masking_key(s)

            s += 1
            If s = 4 Then s = 0
        Next

        LblSock.Text += vbCrLf + "Sending string: " + txtsock.Text
        LblSock.Text += vbCrLf + "Sending bytes: "

        For i = 0 To bytesSent.Length - 1
            LblSock.Text += bytesSent(i).ToString() + ","
        Next

        sock.socket.Send(bytesSent)
    ElseIf (txtsock.Text.Length <= 65535) Then
        request = "11111111" & request

        Dim ascii As Encoding = Encoding.UTF8
        Dim bytesSent As Byte() = ascii.GetBytes(request)

        bytesSent(0) = &H80 Or 1
        bytesSent(1) = 126 Or &H80
        bytesSent(2) = BitConverter.GetBytes(txtsock.Text.Length)(1)
        bytesSent(3) = BitConverter.GetBytes(txtsock.Text.Length)(0)
        bytesSent(4) = masking_key(0)
        bytesSent(5) = masking_key(1)
        bytesSent(6) = masking_key(2)
        bytesSent(7) = masking_key(3)

        Dim s As Integer = 0
        For i = 8 To bytesSent.Length - 1
            bytesSent(i) = bytesSent(i) Xor masking_key(s)

            s += 1
            If s = 4 Then s = 0
        Next

        LblSock.Text += vbCrLf + "Sending string: " + txtsock.Text
        LblSock.Text += vbCrLf + "Sending bytes: "

        For i = 0 To bytesSent.Length - 1
            LblSock.Text += bytesSent(i).ToString() + ","
        Next

        sock.socket.Send(bytesSent)
    Else
        request = "1111111112222" & request

        Dim ascii As Encoding = Encoding.UTF8
        Dim bytesSent As Byte() = ascii.GetBytes(request)

        bytesSent(0) = &H80 Or 1
        bytesSent(1) = 126 Or &H80
        bytesSent(2) = BitConverter.GetBytes(txtsock.Text.Length)(0)
        bytesSent(3) = BitConverter.GetBytes(txtsock.Text.Length)(1)
        bytesSent(4) = BitConverter.GetBytes(txtsock.Text.Length)(2)
        bytesSent(5) = BitConverter.GetBytes(txtsock.Text.Length)(3)
        bytesSent(6) = BitConverter.GetBytes(txtsock.Text.Length)(4)
        bytesSent(7) = BitConverter.GetBytes(txtsock.Text.Length)(5)
        bytesSent(8) = BitConverter.GetBytes(txtsock.Text.Length)(6)
        bytesSent(9) = BitConverter.GetBytes(txtsock.Text.Length)(7)
        bytesSent(10) = masking_key(0)
        bytesSent(11) = masking_key(1)
        bytesSent(12) = masking_key(2)
        bytesSent(13) = masking_key(3)

        Dim s As Integer = 0
        For i = 13 To bytesSent.Length - 1
            bytesSent(i) = bytesSent(i) Xor masking_key(s)

            s += 1
            If s = 4 Then s = 0
        Next

        LblSock.Text += vbCrLf + "Sending string: " + txtsock.Text
        LblSock.Text += vbCrLf + "Sending bytes: "

        For i = 0 To bytesSent.Length - 1
            LblSock.Text += bytesSent(i).ToString() + ","
        Next

        sock.socket.Send(bytesSent)
    End If
    LblSock.ScrollToEnd()
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 2015-08-10
    • 2020-06-28
    • 2017-01-10
    • 2015-06-09
    相关资源
    最近更新 更多