Buffering TCP Data

From HashVB
Jump to: navigation, search

When working with TCP, you cannot guarantee that data will arrive in the way it was sent. That is to say that if one set of packets arrives before another set of packets, you could end up with only half the data you expected in one message. What this means is that it is necessary to buffer TCP data until you receive your delimeter character(s) (usually \r\n, or vbCrLf) before processing it. The following is a simple solution to this problem -

Add a class module to your project, and call it something like CTcpBuffer, then paste the following code into it:

   Option Explicit
   Public Delimiter As String
   Dim Buff As String
   Public Event WalkBuff(ByVal Data As String)
   Private Sub Class_Initialize()
       Delimiter = vbCrLf
   End Sub
   Public Sub AddData(ByVal Data As String)
       Buff = Buff & Data
   End Sub
   Public Function GetData(ByVal Length As Long) As String
       Dim ret As String
       ret = Left$(Buff, Length)
       Buff = Mid$(Buff, Length + 1)
       GetData = ret
   End Function
   Public Sub WalkBuffer()
       Do While InStr(Buff, Delimiter) > 0
           RaiseEvent WalkBuff(GetData(InStr(Buff, Delimiter) + Len(Delimiter) - 1))
   End Sub
   Public Property Get Buffer() As String
       Buffer = Buff
   End Property

Then use the code as follows:

   Dim WithEvents mTcpBuffer As CTcpBuffer
   Private Sub Form_Load()
       Set mTcpBuffer = New CTcpBuffer
       mSocket.Connect "someserver", 1234
   End Sub
   Private Sub Form_Terminate()
       Set mTcpBuffer = Nothing
   End Sub
   Private Sub mSocket_DataArrival(ByVal BytesTotal As Long)
       Dim sData As String
       mSocket.GetData sData, vbString, BytesTotal
       mTcpBuffer.AddData sData
   End Sub
   Private Sub mTcpBuffer_WalkBuff(ByVal Data As String)
       '-- Process Data Here
   End Sub

Simple as that. The class even has features for when you want to use something other than \r\n as a delimiter (though you shouldn't ever, really).

See also