EndReceive Never never finishes receiving vb Net

1.2k views Asked by At

i'm using the example of Microsoft (Visual Basic net 4.5) to send and receive datas throw socket, but this block is always true:

    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

But i send, and send, and send message, short or large, and it never enter to the else sentence. Here, my initial code:

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

I do recive the messages that the server sends, and i can see them in Visual Studio steps to steps, but i don`t know why it never enters to the else, i mean, it never finish receiving datas.

I read the answer of Marc Gravell but i prefer a code example of how to solve this, i didn't know what to do.

Moreover, i removed "else" and it fill my textBox with to many white lines, like a infite loop of many receives. Please help me. Thanks.

Oh Sorry, here is the Escuchador Function:

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
1

There are 1 answers

3
Roland Bär On BEST ANSWER

As you already link to the answer of Marc Gravell, his first sentence in the important one:

"EndReceive may well get a 0 if the stream is closed and all data has been consumed."

As long as the stream is open you will never get 0 from EndReceive. You have to process the data you've got according to your Protocol to find the end of your message and send the response.

And as you've asked for some code, here is your code with comments where to put the additional parts:

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