Android Question asyncstream prefix problem

Dirk A

Member
Licensed User
Longtime User
Hello ,
I'm trying to implement the asyncstream prefix mode to send files over a socket, my server side is a Delphi application, the client side is my b4a app.
In delphi I always send the length of the data first followed by the data. In b4a I always get the following runtime error :
'Error: (RuntimeException) java.lang.RuntimeException: Message size too large. Prefix mode can only work if both sides of the connection follow the 'prefix' protocol. '

I've tried to switch the Endianness but with no effect.
When I send the length in my server app , do i have to add a carriage return + linefeed or not ?
 

Dirk A

Member
Licensed User
Longtime User
Well this is a piece of the Delphi code where I send the file , don't know if it will be of any help ( it's part of an indy 10 tcp server)
B4X:
f    :=  tFilestream.Create('test.txt',fmopenread);   
myContext.Connection.IOHandler.Write(IntToStr(F.Size) ) ;
myContext.Connection.IOHandler.Write(f);
 
Upvote 0

Dirk A

Member
Licensed User
Longtime User
ok I adjusted my code and now I don't get the exception.
One more question : in the file transfer desktop example (c#) in the sendFile function , before the file length is written , STREAM_PREFIX is written.
STREAM_PREFIX = -2 , what is this for ?Is it the protocol ? When I try it I get negativearraysizeException in B4A
thank you
 
Upvote 0

kabron

Member
Licensed User
Longtime User
Hello, Erel
I have the same error message but only time to time.
I send a data stream over Bluetooth and it could lasts from a couple of minutes to hour with no errors, but then I got Stream_Error with this java diagnostic. And I got a wrontg Buffer.Length value.

The data consists of continuous 8 bytes packets @ 460800 baud separated with 1ms intervals. I 'm sure that my SW has enough time to process data till next packet. Could it be affected by other processes in the operation system? And could transfering this activity to service mode be helpful?

Thanks in advance,
Vladimir
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
Ciao
you should create a protocol to handle data checking. If some byte is lost, you are not able to find packet beginning. Do you use binary data? If so the trick is a little problematic. You'd have to put a CRC at the end of the packet, to check data integrity.
As I always told my customers: "Gimme a coffe machine and I'll connect to your PC!"

Ciao
Mauro
 
Upvote 0

kabron

Member
Licensed User
Longtime User
Hi, tigrot
The problem is that in prefix mode the control is doing deeply inside java enviroment, so I deal only with it's result. I could not use any additional protocol, because at the moment of error the stream connection is always already broken.

From the other side, in non prefix mode the realized mechanism of buffer filling control is so ineffective that real rate occured be thousands times slow than physical baudrate setted. New_data event raises at unpredictable buffer filling and you have to get this data even if it is a couple of bytes. But then Sub is over and the next time it can raise at 20ms or later.
 
Upvote 0

kabron

Member
Licensed User
Longtime User
Seems it was bad Blutooth Dongle.
Another question:
in case of falling in AStream_Error, is there a way to reestablish connection on the fly?
 
Upvote 0

kabron

Member
Licensed User
Longtime User
One more question:
I successfuly made prefix mode data exchange between uC and Android at 460800 baud. But some problems still exist.
1. If I start uC transmission after BT connection established everything runs OK as expected.
2. But if I made connection while uC transmission is running, I got in 50/50 cases errors concerned message size. I found it reasonable as the received data randomly may occure in the middle off message.
3. I tryed to find solution to somehow syncronize the receiving procces by sending void messages: 0, 0, 0, 0 between the data messages. I logically assume that these short and correct data packets must correctly received in all cases. But the situation became even worse I could not establish communication at all. Does it means that such 0,0,0,0 packets are illegal for prefix mode? May be longer packets such as 0,0,0,8, 0,0,0,0, 0,0,0,0 will solve the problem?
And if not, is there a way to establish connection on the fly while transmitter is permanently sending?
I do know that there is a way to make some kind of handshaking by sending to the uC stop command and then to start it. But it is not acceptible in my case.
Any help appreciated.

Thanks in advance
 
Upvote 0

kabron

Member
Licensed User
Longtime User
Hello, Erel
unfortunately it is not possible to use non prefix mode due to tremendous time lags between New_Data events.
I need as high data rate as possible. Also I need binary transfer.
And , please, confirm that the 0,0,0,0 packet is illegal in the prefix mode. But IMHO it's against the logic. Maybe you could decribe why so?
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Non prefix mode is not slower than prefix mode.

The problem is not with the 0,0,0,0 packet. The problem is that in prefix mode there is no way to "reset" it. It will read the 4 random bytes that it receives and interpret them as the message length. This will cause it to either crash because of an out of memory error or wait for a very long time until there is enough data.
 
Upvote 0

PhillipMorris

Member
Licensed User
Longtime User
Hello, I am getting the same message
'Error: (RuntimeException) java.lang.RuntimeException: Message size too large. Prefix mode can only work if both sides of the connection follow the 'prefix' protocol.'
when I am trying to send a string with vb.net

My code in vb :
B4X:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If stream.CanWrite Then
            Dim myWriteBuffer As Byte() = Encoding.UTF8.GetBytes("arka")
            stream.Write(myWriteBuffer, 0, myWriteBuffer.Length)
            stream.Flush()
        End If
    End Sub

I also tried Encoding.ASCII

Please help.
 
Upvote 0

PhillipMorris

Member
Licensed User
Longtime User
OK. Finally got it. It was pretty obvious, but I did not read it carefully.
Just for the record, here is the code for VB.NET 2013 :

B4X:
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If stream.CanWrite Then
            Dim Buffer As Byte() = Encoding.UTF8.GetBytes("testing123")

            Dim BufferLen As Integer = Buffer.Length
            Dim Prefix As Byte() = BitConverter.GetBytes(BufferLen)

            stream.Write(Prefix, 0, Prefix.Length)
            stream.Write(buffer, 0, buffer.Length)
            stream.Flush()
        End If
    End Sub

...and thanks to Erel for the great support.
 
Upvote 0
Top