首页 文章

websocket 在握手后停止响应

提问于
浏览
0

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

看起来我通过握手很好,在收到一个文本框后,数据停止接收。

websocket 服务器是.net 核心 Azure 项目作为 echo 工作。使用简单的 websocket 客户端镀铬扩展与多个连接工作得很好。

这是我的 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 ---

VbCode:

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

1 回答

  • 0

    感谢 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
    

相关问题