【问题标题】:EndReceive Never never finishes receiving vb NetEndReceive 永远不会完成接收 vb Net
【发布时间】:2023-04-03 08:08:01
【问题描述】:

我正在使用example of Microsoft(Visual Basic net 4.5)发送和接收数据抛出套接字,但这个块总是正确的:

    Private Sub OnRecieve(ByVal ar As IAsyncResult)
    Try
        Dim state As StateObject = CType(ar.AsyncState, StateObject)
        Dim client As Socket = state.workSocket

        ' Read data from the remote device.
        Dim bytesRead As Integer = client.EndReceive(ar)

        If bytesRead > 0 Then
            ' There might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead))

            '  Se supone que vuelve por los datos que faltan, pero no lo hace (Creo)
            client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf OnRecieve, state)

        Else
            ' All the data has arrived; put it in response.
            If state.sb.Length > 1 Then
                VariablesGlobales.response = state.sb.ToString()
            End If
            ' Signal that all bytes have been received.
            receiveDone.Set()
        End If


    Catch ex As Exception
        'clientSocket.Close()
        RaiseEvent FallaAlRecibirDatos(ex.Message, "Falla en endReive.")
    End Try

End Sub

但是我发送、发送、发送消息,无论是短消息还是大消息,它都不会进入 else 语句。在这里,我的初始代码:

Public Sub Conectar()

    clientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

    Dim ipEndPoint As IPEndPoint = New IPEndPoint(Me.ipAddress, VariablesGlobales.Puerto)
    clientSocket.BeginConnect(ipEndPoint, New AsyncCallback(AddressOf OnConnect), clientSocket)

    ' Wait for connect.
    connectDone.WaitOne()

    EnviarDatosPersonales()

    ' Wait for send datas.
    sendDone.WaitOne()

    While True
        AvtivarEscuchador()
        receiveDone.WaitOne()

        DescifrarMsg(VariablesGlobales.response)
    End While
End Sub

我确实收到了服务器发送的消息,我可以在 Visual Studio 中逐个步骤地看到它们,但我不知道为什么它永远不会进入 else,我的意思是,它永远不会完成接收数据。

我阅读了the answer of Marc Gravell,但我更喜欢如何解决这个问题的代码示例,我不知道该怎么做。

此外,我删除了“else”,它用许多白线填充了我的文本框,就像许多接收的无限循环。请帮我。谢谢。

抱歉,这里是 Escuchador 函数:

Private Sub AvtivarEscuchador()

    ' Borramos los datos de respuesta anterior
    VariablesGlobales.response = ""

    ' Activamos el escuchador
    Try
        ' Create the state object.
        Dim state As New StateObject()
        state.workSocket = Me.clientSocket

        ' Begin receiving the data from the remote device.
        Me.clientSocket.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf OnRecieve, state)
    Catch e As Exception
        RaiseEvent FallaAlRecibirDatos("No se pudo activar el escuchador.", "Falla al intentar escuchar.")
    End Try

End Sub

【问题讨论】:

  • 您是否至少调用过一次client.BeginReceivebytesRead 的初始值是多少?
  • 我用更多代码编辑了这个问题。
  • bluesky777,我还是没看到你打电话给BeginReceive。你觉得OnRecieve不叫BeginRecv会怎么叫
  • 使用 BeginXxx() 方法根本没有任何意义,您总是等待它们完成。因此,只需使用这些方法的同步版本,就可以让您的代码更简单、更容易调试。

标签: .net vb.net sockets beginreceive


【解决方案1】:

正如您已经链接到 Marc Gravell 的答案,他在重要的第一句话中的第一句话:

“如果流已关闭并且所有数据都已被消耗,EndReceive 很可能会得到 0。”

只要流是打开的,您就永远不会从 EndReceive 获得 0。您必须根据您的协议处理您获得的数据,以找到消息的结尾并发送响应。

正如您所要求的一些代码,这里是您的代码与 cmets 放置附加部分的位置:

If bytesRead > 0 Then
    ' There might be more data, so store the data received so far.
    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead))

    ' Put here code to check for protocol end (for example \0) in your buffer state.sb
    ' and handle protocol if found. The rest of the buffer should remain in the buffer
    ' as it could be part of the next protocol.

    ' if you only except one message, set receiveDone.Set() here if message received
    ' completely

    '  Se supone que vuelve por los datos que faltan, pero no lo hace (Creo)
    client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf OnRecieve, state)

Else
    'connection was closed
    ' handle existing information if appropreate
    receiveDone.Set()
End If

【讨论】:

  • 谢谢,但 Microsoft 示例中没有显示。如您所见,我调用 DescifrarMsg(VariablesGlobales.response) 函数来处理数据并将响应插入到 Chat 文本框。我是否必须关闭套接字才能完成接收数据并重新打开才能继续收听? PD:为什么我的问题是-1? :O
  • 用“代码”更新答案。您不必关闭套接字,只需处理您收到的所有数据并以您有结束信息的方式选择协议(如'\0')。
  • 谢谢。我用这个: **If** state.sb.ToString.Contains("\0") Then <b>Dim</b> textoMsg As String = state.sb.ToString <b>textoMsg</b> = textoMsg.Substring(0, textoMsg.LastIndexOf("\0")) <b>DescifrarMsg(textoMsg)</b> Return End If 现在可以继续了,非常感谢。快乐:)
猜你喜欢
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 2018-05-11
相关资源
最近更新 更多