Skip to main content
removed networking code
Source Link
M.M
  • 461
  • 1
  • 5
  • 12

I amThis code extracts packets from some data I've received using the asynchronous read functions of TcpClient, and whenever a newline character is received, the handle_packet function should be called with the data so far, excluding the newline. It is possible that multiple packets will be received in a single read, and/or partial packets.

Private inbuf(10000) As Byte
Private inoff As Integer
Private serv As NetworkStream

Public Sub DoRead()
    serv.BeginRead(inbuf, inoff, inbuf.Length - inoff, New AsyncCallback(AddressOf OnRead), serv)
End Sub

Private Sub OnRead(ByVal R As IAsyncResult)
    Dim readlen = serv.EndRead(R)

    inoff = inoff + readlen

    If readlen = 0 Then
        Return  ' this happens when socket is closed or whatever
    End IfProcessBuffer

    ' It's possible that this ReadBuffer willmay receivecontain multiple packets, so split it updelimited by delimitera newline
    Do While 1
        Dim newline As Byte = 10
        Dim newline_index = System.Array.IndexOf(Of Byte)([inbuf], newline) ' I think this is zero-based index
        Dim Data As String = Nothing  ' if I leave this initializer out then Data seems to retain its value for next loop iteration

        If (newline_index >= 0 AndAlso newline_index < inoff) Then   ' packet found
            Data = Encoding.ASCII.GetString(inbuf, 0, newline_index)
            inbuf = inbuf.Skip(newline_index + 1).ToArray()
            ReDim Preserve inbuf(10000) ' the Skip shortened the array
            inoff = inoff - (newline_index + 1)
            If inoff < 0 Then inoff = 0 ' shouldn't happen but seems to happen sometimes?
        End If

        ' If we did not find a newline (or the input was empty string), it means we need to wait for more input
        If String.IsNullOrEmpty(Data) Then
            serv.BeginRead(inbuf, inoff, inbuf.Length - inoff, New AsyncCallback(AddressOf OnRead), serv)
            Return
        End If

        ' Process the response string
        handle_packet(Data)
    Loop
End Sub

I am using the asynchronous read functions of TcpClient, and whenever a newline character is received, the handle_packet function should be called with the data so far, excluding the newline. It is possible that multiple packets will be received in a single read, and/or partial packets.

Private inbuf(10000) As Byte
Private inoff As Integer
Private serv As NetworkStream

Public Sub DoRead()
    serv.BeginRead(inbuf, inoff, inbuf.Length - inoff, New AsyncCallback(AddressOf OnRead), serv)
End Sub

Private Sub OnRead(ByVal R As IAsyncResult)
    Dim readlen = serv.EndRead(R)

    inoff = inoff + readlen

    If readlen = 0 Then
        Return  ' this happens when socket is closed or whatever
    End If

    ' It's possible that this Read will receive multiple packets, so split it up by delimiter
    Do While 1
        Dim newline As Byte = 10
        Dim newline_index = System.Array.IndexOf(Of Byte)([inbuf], newline) ' I think this is zero-based index
        Dim Data As String = Nothing  ' if I leave this initializer out then Data seems to retain its value for next loop iteration

        If (newline_index >= 0 AndAlso newline_index < inoff) Then   ' packet found
            Data = Encoding.ASCII.GetString(inbuf, 0, newline_index)
            inbuf = inbuf.Skip(newline_index + 1).ToArray()
            ReDim Preserve inbuf(10000) ' the Skip shortened the array
            inoff = inoff - (newline_index + 1)
            If inoff < 0 Then inoff = 0 ' shouldn't happen but seems to happen sometimes?
        End If

        ' If we did not find a newline (or the input was empty string), it means we need to wait for more input
        If String.IsNullOrEmpty(Data) Then
            serv.BeginRead(inbuf, inoff, inbuf.Length - inoff, New AsyncCallback(AddressOf OnRead), serv)
            Return
        End If

        ' Process the response string
        handle_packet(Data)
    Loop
End Sub

This code extracts packets from some data I've received using TcpClient.

Private inbuf(10000) As Byte
Private inoff As Integer

Private Sub ProcessBuffer

    ' Buffer may contain multiple packets, delimited by a newline
    Do While 1
        Dim newline As Byte = 10
        Dim newline_index = System.Array.IndexOf(Of Byte)([inbuf], newline) ' I think this is zero-based index
        Dim Data As String = Nothing  ' if I leave this initializer out then Data seems to retain its value for next loop iteration

        If (newline_index >= 0 AndAlso newline_index < inoff) Then   ' packet found
            Data = Encoding.ASCII.GetString(inbuf, 0, newline_index)
            inbuf = inbuf.Skip(newline_index + 1).ToArray()
            ReDim Preserve inbuf(10000) ' the Skip shortened the array
            inoff = inoff - (newline_index + 1)
            If inoff < 0 Then inoff = 0 ' shouldn't happen but seems to happen sometimes?
        End If

        ' If we did not find a newline (or the input was empty string), it means we need to wait for more input
        If String.IsNullOrEmpty(Data) Then
            Return
        End If

        ' Process the response string
        handle_packet(Data)
    Loop
End Sub
edited tags
Link
200_success
  • 144.1k
  • 22
  • 188
  • 473
Source Link
M.M
  • 461
  • 1
  • 5
  • 12

Find and extract delimited packet in buffer

I'm writing in VB.NET, using VS Community 2013. I don't know much about this language. I have managed to make my code work, but I suspect it is possible to improve the code a lot.

I am using the asynchronous read functions of TcpClient, and whenever a newline character is received, the handle_packet function should be called with the data so far, excluding the newline. It is possible that multiple packets will be received in a single read, and/or partial packets.

Private inbuf(10000) As Byte
Private inoff As Integer
Private serv As NetworkStream

Public Sub DoRead()
    serv.BeginRead(inbuf, inoff, inbuf.Length - inoff, New AsyncCallback(AddressOf OnRead), serv)
End Sub

Private Sub OnRead(ByVal R As IAsyncResult)
    Dim readlen = serv.EndRead(R)

    inoff = inoff + readlen

    If readlen = 0 Then
        Return  ' this happens when socket is closed or whatever
    End If

    ' It's possible that this Read will receive multiple packets, so split it up by delimiter
    Do While 1
        Dim newline As Byte = 10
        Dim newline_index = System.Array.IndexOf(Of Byte)([inbuf], newline) ' I think this is zero-based index
        Dim Data As String = Nothing  ' if I leave this initializer out then Data seems to retain its value for next loop iteration

        If (newline_index >= 0 AndAlso newline_index < inoff) Then   ' packet found
            Data = Encoding.ASCII.GetString(inbuf, 0, newline_index)
            inbuf = inbuf.Skip(newline_index + 1).ToArray()
            ReDim Preserve inbuf(10000) ' the Skip shortened the array
            inoff = inoff - (newline_index + 1)
            If inoff < 0 Then inoff = 0 ' shouldn't happen but seems to happen sometimes?
        End If

        ' If we did not find a newline (or the input was empty string), it means we need to wait for more input
        If String.IsNullOrEmpty(Data) Then
            serv.BeginRead(inbuf, inoff, inbuf.Length - inoff, New AsyncCallback(AddressOf OnRead), serv)
            Return
        End If

        ' Process the response string
        handle_packet(Data)
    Loop
End Sub