-1

我正在使用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,我的意思是,它永远不会完成接收数据。

我阅读了 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
4

1 回答 1

0

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

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

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

正如您所要求的一些代码,这是您的代码,其中包含将附加部分放在何处的注释:

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
于 2013-08-27T15:49:33.187 回答