Array size to large

XverhelstX

Well-Known Member
Licensed User
Longtime User
Hello everyone,

I succesfully made a connection with my server written in vb.net, but when I try to send a message from my server to the client (my device), it force closes.
In my app I have the following log:

FATAL EXCEPTION: Thread-10
java.lang.OutOfMemoryError: array size too large
at anywheresoftware.b4a.randomaccessfile.AsyncStreams$AIN.run(AsyncStreams.java:163)
at java.lang.Thread.run(Thread.java:1019)
Force finishing activity anywheresoftware.b4a.samples.network/.main

Server side:

B4X:
Private Sub dat(ByVal dat As String)
        Dim nstream As NetworkStream = sock.GetStream()
        Dim bit As [Byte]() = System.Text.Encoding.UTF8.GetBytes(dat)
        nstream.Write(bit, 0, bit.Length)
    End Sub


    Private Sub Btn_Connect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btn_Connect.Click
        dat("0")
    End Sub

end sub

Client side:

B4X:
Sub Process_Globals
    Dim AStreams As AsyncStreams
    Dim Server As ServerSocket
    Dim Socket1 As Socket
   
   Dim TEXT_BYTE, IMAGE_BYTE, IMAGEOK_BYTE As Byte
   TEXT_BYTE = 1
   IMAGE_BYTE = 2
   IMAGEOK_BYTE = 3
End Sub
Sub Globals
    Dim EditText1 As EditText
   Dim BC As ByteConverter
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        Server.Initialize(10130, "Server")
        Server.Listen
        Log("MyIp = " & Server.GetMyIP)
    End If
    EditText1.Initialize("EditText1")
    EditText1.ForceDoneButton = True
    Activity.AddView(EditText1, 10dip, 10dip, 300dip, 60dip)
End Sub

Sub Activity_Resume

End Sub
Sub Activity_Pause(UserClosed As Boolean)
    If UserClosed Then
        Log("closing")
        AStreams.Close
        Socket1.Close
    End If
End Sub

Sub Server_NewConnection (Successful As Boolean, NewSocket As Socket)
    If Successful Then
        ToastMessageShow("Connected", False)
        Socket1 = NewSocket
        AStreams.InitializePrefix(Socket1.InputStream, False, Socket1.OutputStream, "AStreams")
    Else
        ToastMessageShow(LastException.Message, True)
    End If
    Server.Listen
End Sub

Sub AStreams_NewData (Buffer() As Byte)
    Dim msg As String
    msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    ToastMessageShow(msg, False)
    Log(msg)
End Sub

Sub AStreams_Error
    ToastMessageShow(LastException.Message, True)
End Sub

Sub AddCommandToBytes(Command As Byte, Buffer() As Byte, Length As Int) As Byte()
   Dim b(Length + 1) As Byte
   b(0) = Command
   BC.ArrayCopy(Buffer, 0, b, 1, Length)
   Return b
End Sub

Any help?

XverhelstX
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
Oh, great Erel, It works without prefix.
but now I receive like tons of messages?

B4X:
Dim imgStream As MemoryStream = New MemoryStream()

        BMPEndResult.Save(imgStream, System.Drawing.Imaging.ImageFormat.Png)

        imgStream.Close()
        Dim byteArray As Byte() = imgStream.ToArray()

        strResult = Convert.ToBase64String(byteArray)
        dat("0" & strResult)

B4X:
Sub AStreams_NewData (Buffer() As Byte)
    Dim msg As String
    msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    Msgbox(msg, "")
    Log(msg)
End Sub

What I mean is that different messageboxes open.
Isn't it possible to put everything in one messagebox? (so pry then I have to work with prefix mode though, however I have no idea on how to do this in vb.net)
Thanks a lot!

XverhelstX
 
Last edited:
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
Nope I don't get any broken messages.
The problem I have is that i want all received data to have in 1 messagebox.

Now when I do dat("0"), 0 appears on my Android Device, but when I send the following:

B4X:
 Dim imgStream As MemoryStream = New MemoryStream()

        BMPEndResult.Save(imgStream, System.Drawing.Imaging.ImageFormat.Png)

        imgStream.Close()
        Dim byteArray As Byte() = imgStream.ToArray()

        strResult = Convert.ToBase64String(byteArray)
        dat(strResult)

I receive more than 1 messagebox sometimes 2, 3 or even 4, depending on the size of BMPEndResult.
Now I just want to receive all data at once, so I can decode it.

XverhelstX
 
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
Oh, Thanks Agraham!
I think i get it.

As Erel stated, I'd have to write my own code at the server side.
I just did the following:
B4X:
dat(strResult.Length & strResult)
strResult.Length returns me 18068
And all messages lengths:

B4X:
Msgbox(msg,msg.Length)

2 920 + 6 393 + 5 840 + 1 460 + 1 460 = 18 073

So 18 073 - 18 068 = 5.

Is it always 5? or is it because 5 messageboxes showed up?
Is there a way to calculate on how many packages will be send?

So how should I do that? Are therz any tutorials on how to parse the data? :s

xverhelstx
 
Last edited:
Upvote 0

agraham

Expert
Licensed User
Longtime User
I don't understand your last post but you can't predict anything about packet size and number. That's up to the underlying TCP handler.

To use prefix mode you need to send the length of the message in bytes as four bytes and then the message. If you are using VB.NET you might need to consider the endian-ness of the four bytes which are converted to an int according to the endian-ness specified in InitializePrefix.
 
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
Damn, I still don't get it :s

Do you have some kind of example.
I can't seem to find on how to do it. :confused:
So first I should send a package with the length of strResult, right?
but how do I send it as four bytes? I can't find it on the net.
and then the actual message.

XverhelstX
 
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
Ow great!
It worked, thanks Erel and Agraham!

If someone is intrested here is the code:

B4X:
Private Sub dat(ByVal dat As String)
        Dim nstream As NetworkStream = sock.GetStream()
        Dim bit As Byte() = System.Text.Encoding.UTF8.GetBytes(dat)
        Dim bytes() As Byte = BitConverter.GetBytes(bit.Length)
        Dim intLength As Integer = BitConverter.ToInt32(bytes, 0)
        Dim bw As New BinaryWriter(sock.GetStream())
        bw.Write(intLength)
        nstream.Write(bit, 0, bit.Length)

    End Sub

I hope it is correct, if not, please say :S

XverhelstX
 
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
Thanks Erel.
But I still have some questions:

Using this code:

B4X:
Private Sub datPrefix(ByVal dat As String)
        If sock.Connected = True Then
            Dim nstream As NetworkStream = sock.GetStream()
            Dim bit As Byte() = System.Text.Encoding.UTF8.GetBytes(dat)
            Dim bw As New BinaryWriter(sock.GetStream())
            bw.Write(bit.Length)
            nstream.Write(bit, 0, bit.Length)
        Else
            MessageBox.Show("Not Connected", "")
        End If


End Sub

But how can I handle with this now if I want to add an identifier at the beginning to work with this:

B4X:
datPrefix("1" + strResult)

B4X:
Sub AStreams_NewData (Buffer() As Byte)

Dim command As Byte
command = Buffer(0)
Msgbox(command,"")
   Select command
      Case 1
         Msgbox(command,"") '1 should be displayed here.
      Case IMAGE_BYTE
         Dim b(Buffer.Length-1) As Byte
         'BC.ArrayCopy(Buffer, 1, b, 0, Buffer.Length-1)
         Log("Array copied")
         'Camera1.uploadFrame(strIndexPHPUniqueKey, b, strLinkToPluginPHP)
      Case IMAGEOK_BYTE
         
   End Select
   
End Sub

Thanks!

XverhelstX
 
Upvote 0
Top