Android Question bytes array max size ?

mirekk36

Member
Licensed User
Longtime User
I would like send via TCP files from PC. I use asyncstreams with prefix. I write received tcp file like here

B4X:
Sub tcpsrv_NewConnection (Successful As Boolean, NewSocket As Socket)
    If Successful Then
        ToastMessageShow("Connected", False)
        lbRek1.Text = "receiving file..."
        socket1 = NewSocket
        AStreams.InitializePrefix(socket1.InputStream, False, socket1.OutputStream, "AStreams")
    Else
        ToastMessageShow(LastException.Message, True)
    End If
    serverTcp.Listen
End Sub

Sub AStreams_Terminated
    lbRek1.Text = "File received succesfully!"
End Sub

Sub AStreams_NewData (Buffer() As Byte)
 
    WriteFile( File.DirRootExternal&"/mkbootloader/", "ala.avi", Buffer )
  
End Sub


Sub WriteFile(Dir As String, FileName As String, data() As Byte)
  
    Dim out As OutputStream
    out = File.OpenOutput(Dir, FileName, True)
    out.WriteBytes(data, 0, data.Length )
    out.Close
End Sub

The problem is when I try send bigger files (over for example 20 MB) .... Then my b4a app crashers, o doin'g nothing ...

If I send smaller files below 20 MB there will work great for me ;) ... but ... what with bigger files ? Any idea what I do wrong ?
 

mirekk36

Member
Licensed User
Longtime User
I will send for example a big file 200 MB from PC to my smartphone/android, not upload from smartphone

so the big problem is in fact that if I initialize asyncstreams ... then if I send a big so file .... I have error that there is not enought free memory (I think RAM memory) in system .... for so big stream.

Also I have to divide file before send on PC side for small chunks, I can do that (not a problem) ... but I don't know how to do it on Android side in B4A ... How can I receive with AsyncStreams smaller chunks in one TCP session ?

any ideas ? please
 
Upvote 0

mirekk36

Member
Licensed User
Longtime User
ok thx I have solved my problem. There was big mistake in my PC application which did dividing big stream into smaller streams ;) ... Now all work OK ;)
 
Upvote 0

mirekk36

Member
Licensed User
Longtime User
Erel I'm feeling it's a great advice ;) but ... because I'm newbie in B4A ... I can't think how can I use it in my code ? :(

So I hope first I should start Asyncstreams like here:

B4X:
Sub tcpsrv_NewConnection (Successful As Boolean, NewSocket As Socket)
    If Successful Then
        socket1 = NewSocket
        AStreams.InitializePrefix(socket1.InputStream, False, socket1.OutputStream, "AStreams")
    End If
    serverTcp.Listen
End Sub

is that right ?

And when and how should I use AsyncStreams.WriteStream ?

I have tryed it in

B4X:
Sub AStreams_NewData (Buffer() As Byte)

        AStreams.WriteStream( socket1.InputStream, File.OpenOutput(File.DirRootExternal", "recfilename", True) )


End Sub

but it's wrong way .... only errors
 
Upvote 0

mirekk36

Member
Licensed User
Longtime User
Erel I have a question about streams .... I see your code in C#

I see that in PREFIX mode, we should send at first in stream:

1. length of filename (4 bytes)
2. Filename (string)
3. STREAM_PREFIX (it's 4 bytes integer with value -2 ? right? ... why -2 ?)
4. FileSize (4 bytes integer or 8 bytes ? Int64?)
5. .... here we send data from file in chunks - every 8192 bytes (we calculate Adler checksum too)
6. Adler checksum ( 4 bytes )

So my question is:

1. should we ALWAYS use such prefix mode ?
2. should we ALWAYS calculate and send Adler checksum ?

I ask about it because I have to do my program in Delphi. When I don't use Prefix mode and I send files without adler checksum .... (I'm wondered it works ... but only one disadantage - I never become enent named "AStream_NewStream" I always become "AStream_Terminated" ..

But files that I have send from PC to smartphone are good (JPG's, AVI's, MP3, TXT and many others)

If I could know details about dealing with streams



B4X:
                Adler32 adler = new Adler32();
                log("Sending: " + fileToSend);
                using (FileStream fs = new FileStream(fileToSend, FileMode.Open))
                {
                    byte[] name = Encoding.UTF8.GetBytes(Path.GetFileName(fileToSend));
                    BinaryWriter bw = new BinaryWriter(stream);
                    //send the first message which is the file name
                    bw.Write(name.Length);
                    bw.Write(name);
                    //send the stream message
                    bw.Write(STREAM_PREFIX);
                    long size = new FileInfo(fileToSend).Length;
                    bw.Write(size);
                    long written = 0;
                    byte[] buffer = new byte[8192];
                    while (written < size)
                    {
                        int count = fs.Read(buffer, 0, Math.Min((int)(size - written), buffer.Length));
                        stream.Write(buffer, 0, count);
                        adler.Update(buffer, 0, count);
                        written += count;
                    }
                    bw.Write(adler.Value);
                    log("File sent successfully.");
                }
 
Last edited:
Upvote 0

mirekk36

Member
Licensed User
Longtime User
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
WriteStream and the NewStream event are only relevant to prefix mode. You do not need to do anything special if you are not using prefix mode.

once question more .... Erel is that Adler32 ok?
Any correct implementation of Adler32 will work. I do not know whether this code implements the algorithm correctly or not.
 
Upvote 0

mirekk36

Member
Licensed User
Longtime User
for now I have done my own wraper in Delphi for AsyncStreams (for now only for send files from PC) ;) .... there is only (I hope) last problem, Adler checksum

So I have used rawstreams in Delphi to produce AsyncStreams Structure ofcourse with prefix. It works really fine, so after START_PREFIX like in your code from C#, streamed data (from PC from Delphi) are going into the temporary file on my android into specified folder AStreams.StreamFolder. All work's except one ... these adler checksum at the end, because at the end I become Astreams_Error ... (because of wrong checksum i think)

so last question Erel ... Adler32 checksum is send as 64bit ? I think yes, but please about confirmation.
 
Upvote 0

mirekk36

Member
Licensed User
Longtime User
eeeeh Erel - if I display LastException in Astreams_error I have:

java.lang.Exception: CRC value does not match.

this is last step for me ... please help me , maybe where can I find library to see how its CRC is counted in Java ? Or how should be ended stream ? Only if I send these adler CRC 64 bit ? I think yes but something must I do wrong ...

I use exactly this method from C# to caluclate Adler32 crc

B4X:
            //(By Per Bothner)
            uint s1 = checksum & 0xFFFF;
            uint s2 = checksum >> 16;
           
            while (count > 0) {
                // We can defer the modulo operation:
                // s1 maximally grows from 65521 to 65521 + 255 * 3800
                // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
                int n = 3800;
                if (n > count) {
                    n = count;
                }
                count -= n;
                while (--n >= 0) {
                    s1 = s1 + (uint)(buffer[offset++] & 0xff);
                    s2 = s2 + s1;
                }
                s1 %= BASE;
                s2 %= BASE;
            }
           
            checksum = (s2 << 16) | s1;

on start I put checksum = 1, and BASE = 65521;
 
Upvote 0

mirekk36

Member
Licensed User
Longtime User
END of my questions about it ;) .... I report that all done!

all work's !!! like in a dream ;) I can send every (even huge) files form PC to my Android with program in my Delphi !!!

I'm sorry, I'm so glad ... I'm happy like a child ...
 
Upvote 0

RandomCoder

Well-Known Member
Licensed User
Longtime User
END of my questions about it ;) .... I report that all done!

all work's !!! like in a dream ;) I can send every (even huge) files form PC to my Android with program in my Delphi !!!

I'm sorry, I'm so glad ... I'm happy like a child ...
This is why I love programming so much, the exilleration of finaly solving a problem which at first seemed to be impossible :D
 
Upvote 0
Top