4
\$\begingroup\$

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.

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
\$\endgroup\$
  • \$\begingroup\$ Instead of the methods that use the IASyncResult pattern, is it an option for you to use the newer Async methods (ReadAsync, etc.)? .NET 4.5+ would be required. \$\endgroup\$ – moarboilerplate Dec 2 '15 at 23:22
  • \$\begingroup\$ Yes that would be an option \$\endgroup\$ – M.M Dec 2 '15 at 23:28
  • \$\begingroup\$ @moarboilerplate i'm not sure how I would use ReadAsync in this situation; I want my UI to remain responsive while waiting for data and could not find any code examples along those lines (all the examples show executing some other statements simultaneously with the async call, but then blocking for the async call to complete once those other statements are finished) \$\endgroup\$ – M.M Dec 3 '15 at 0:25
  • \$\begingroup\$ I don't have the luxury of being able to do a full write up tonight, but using await will not block, it will return control to the caller until the task is finished, and then subsequent lines will execute. So your loop should suspend until the task completes but not block the UI. Also if you want a pattern closer to the current callback pattern you can use .ContinueWith on the task. Hopefully that helps? \$\endgroup\$ – moarboilerplate Dec 3 '15 at 4:20
  • \$\begingroup\$ @moarboilerplate sort of... I'll try some things on that front. (Note that this doesn't affect the main point of my question, which is the logic for extracting a packet from the buffer) \$\endgroup\$ – M.M Dec 3 '15 at 4:21
1
\$\begingroup\$

Not a full review, but:

If String.IsNullOrEmpty(Data) Then is completely unnecessary. Because Data will be null if you didn't set it within the If portion. Just add an else to the previous if and have it return.

If (newline_index >= 0 AndAlso newline_index < inoff) Then   ' packet found
    ...
else 
    Return
End If

Also your variable names could use some work. I actually don't know what inoff is supposed to stand for here.

\$\endgroup\$
  • \$\begingroup\$ Good catch, I had that around from an earlier iteration of the code that was more complicated \$\endgroup\$ – M.M Dec 4 '15 at 22:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.