Astream.InitializePrefix

derez

Expert
Licensed User
Longtime User
The title is from B4Android, but I would like to implement com with the desktop using this mode.
It adds the length of the message at the begining of the message, so this is simple.
The Problem is how to make the Client.DataAvailable be true only when all the bytes have arrived ? and if the length is bigger then the header - what to do with the rest of the buffer so it will be part of the next message ?
Thanks.
 

derez

Expert
Licensed User
Longtime User
I used the following sub to get the data from the socket and launch another sub when data is ready and stripped from the header. I made a chat application that works between two devices or device and PC, sending and recieving files and messages. It uses Agraham's collection library, Q is a queue object.
The solution is slower then the android side, so if anybody has a better implementation - please tell.
B4X:
Sub Waitfordata_Tick
Dim tbuf(8192) As byte
If Client.DataAvailable = True Then
   count = Stream.ReadBytes(tbuf(),8192)
   For i = 0 To count - 1   ' put tbuf buffer in the Q
      Q.EnqueueByte(tbuf(i))
   Next
   If readflag = False Then  ' the size was not read yet, read it
      For i = 0 To 3
         tb(i) = Q.DequeueByte
      Next
      MsgSize = bc.Int32FromBytes(tb(),0)
      readflag = True   ' size was read and removed from Q
   End If
   If Q.Count >= MsgSize Then  ' the message is all in the Q, get it
      Dim buffer(MsgSize) As byte  
      For i = 0 To MsgSize -1  ' move the message from Q to buffer
         buffer(i) = Q.DequeueByte  
      Next
      readflag = False ' next data in Q is a size
      NewMsg       ' using buffer with the exact MsgSize size
   End If
End If
End Sub
 

agraham

Expert
Licensed User
Longtime User
Queuing individual bytes will be slow as each needs to be wrapped and unwrapped as Objects to be stored in the Queue object. I would use arrays, queuing them if necessary, and marshalling them into smaller or larger arrays as needed using ArrayCopy.
 

derez

Expert
Licensed User
Longtime User
ArrayCopy ! Thanks for the tip !!
After two years of no B4ppc I hardly remember the basics...
 

derez

Expert
Licensed User
Longtime User
This is what I finally did, Q() is a buffer:
B4X:
Sub Waitfordata_Tick
Dim tbuf(8192) As byte
If Client.DataAvailable = True Then
   count = Stream.ReadBytes(tbuf(),8192)
   ArrayCopy(tbuf(),0,count,Q(),endpoint)
   endpoint = endpoint + count
   If readflag = False Then  ' the size was not read yet, read it
      ArrayCopy(Q(),0,4,tb(),0)
      MsgSize = bc.Int32FromBytes(tb(),0)
      readflag = True   ' size was read 
   End If
   If endpoint >= MsgSize+4 AND readflag Then  ' the message is all in the Q, get it
      Dim buffer(MsgSize) As byte  
      ArrayCopy(Q(),4,MsgSize,buffer(),0) ' copy  msg to buffer
      ArrayCopy(Q(),4+msgsize,endpoint - 4 - MsgSize,Q(),0)
      endpoint = endpoint - MsgSize - 4
      readflag = False ' next data in Q is a size
      NewMsg       ' using buffer with the exact MsgSize size
   End If
End If
End Sub
 
Last edited:
Cookies are required to use this site. You must accept them to continue using the site. Learn more…