Buffering TCP Data

From HashVB
Revision as of 09:49, 27 March 2006 by Dee (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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))
       Loop
   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
       mSocket.Close
   End Sub
   
   Private Sub mSocket_DataArrival(ByVal BytesTotal As Long)
       Dim sData As String
       
       mSocket.GetData sData, vbString, BytesTotal
       
       mTcpBuffer.AddData sData
       mTcpBuffer.WalkBuffer
   End Sub
   
   Private Sub mTcpBuffer_WalkBuff(ByVal Data As String)
       '-- Process Data Here
       mSocket.Close
   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