Android Question Astreams TCP connection looses data

Samplatiner

Member
Licensed User
Longtime User
Hello all there,

I am writing an app, in which a small feature should be to take Pictures and send them to a PC.

This Little Feature does not work correctly at a point, which i don't understand why it does not work.


Opening the Connection

B4X:
Dim socket1 As Socket
Dim AStreams As AsyncStreams
'In some Sub
socket1.Initialize("Socket1")
socket1.Connect("192.168.43.180", 4097, 5000)
Well, I make the photo and get the correct data from it. I send the length of the data to the Computer, which receives it correctly.

B4X:
Sub Camera1_PictureTaken(Data() As Byte)
  dataFile=DataDim out As OutputStream
  out=File.OpenOutput(File.DirDefaultExternal, "42.jpg", False)
  out.WriteBytes(Data, 0, Data.Length)
  out.CloseToastMessageShow("Image saved: " & File.Combine(File.DirDefaultExternal, "42.jpg"), True)Dim datalength(4) As Byte
  datalength(0)=(Data.Length/256/256/256)
  datalength(1)=(Data.Length/256/256)
  datalength(2)=(Data.Length/256)
  datalength(3)=Data.Length
  AStreams.Write2(datalength, 0, datalength.Length)
  i = 0
  camera1.StopPreview
End Sub
Afterwards, i send packages of data to the Computer.

B4X:
Sub sendnextData()
  j=0
  Do While j < 2000
    sendData(j)=dataFile(i)
    j=j+1
    i=i+1
  Loop
  AStreams.Write2(sendData, 0, sendData.Length)
End Sub

After each package the PC receives, it sends an acknowledge, so the next package will be sent.
B4X:
Sub AStreams_NewData(Buffer() As Byte)
  If(Buffer(0)=75) Then
    If i < dataFile.Length Then
      sendnextData
    Else
      socket1.Close
    End If
  End If
End Sub

I know that this is still no perfect solution, because the Chance is very low that the file is exactly x*1000 Bytes, but that shall not matter for the moment.

2 times it works fine. But if the tablet sends the third package, the Computer just receives round about 1990 of the 2000 Bytes. The absolut amount of Bytes is not constant.
On the PC there is a Server written in VB, which reads Byte for Byte. Something like this
B4X:
Counter=0
while Counter< datasize
  j=0
  while j< 2000
    FileAsByte(j)=Streamr.Read()
    'save the data to file
    j=j+1
    Counter=Counter+1
  end while
  sendAcknowledge()
end while
If the PC gets only 1990 Bytes, the while Loop does not end and the Programm gets stuck because it waits for data.
Well, I think this simply is not allowed to happen, because TCP guarantees a complete Transmission.
If I reduce the size of the packages to 5 Bytes, I can send round about 27 packages, but then I get the same Problem.

Neither B4A nor VisualStudio throws an exception, error or something like that.

I tried it with "Write" instead of "Write2", same Problem.

Could you give me a hint, where I have to search the Problem?
 
Last edited:

sorex

Expert
Licensed User
Longtime User
shouldn't you add 2000 to counter after each inner loop ending?

if will never reach the datasize value now.
 
Upvote 0

Samplatiner

Member
Licensed User
Longtime User
dthe while Loops are working fine.

If the Problem occurs and i send manually for example by pressing an button a few times something like this

B4X:
Sub Button1_Click()
  Dim Buffer(1) as Byte
  Astreams.Write(Buffer)
End Sub

the Loop works as it has to.

After a few transmissions, the Problem occurs once again. There are packages of Bytes missing

PS:
i could not paste this part of the code because ist on another pc. I had to write it by hand

i edited it.
 
Last edited:
Upvote 0

raphaelcno

Active Member
Licensed User
Longtime User
When you receive 1990 of 2000 Bytes, do you miss the last 10 Bytes or 10 arbitrary Bytes?
What is the value of "i" when the transmission stops, 1989 or 1999?
 
Upvote 0

Samplatiner

Member
Licensed User
Longtime User
Thanks a lot for your help.

I'm still not sure why my last code does not work, but i could find another way.

The Problem was at the vb.net-side.
Because of a reason i don't know, the while Loop counting the received Bytes does not work correctly.

I changed the code to this (This code is written by hand, not copy pasted):

B4X:
while true
try
  'Receive datalength of a package, saved in 2 bytes
  dim datalength as integer = streamr.Read
  datalength = datalength * 256 + streamr.Read
  dim data(datalength) as char
  'if i know how much Byte a package has, i can read exactly this amount of bytes
  streamrServer.Read(data, 0, datalength)
  sendAcknowledge()
Catch
  MessageBox.Show("Success")
  Exit While
End Try
end while

Well, this code works quite well. I have to optimize the speed, because at the moment it's about 4kB/s, but basically the data transfer works.
 
Last edited:
Upvote 0
Top