Android Question Asyncstream terminated ?

AlpVir

Well-Known Member
Licensed User
Longtime User
I need to receive a file PDF from a PC. Use Asyncstream.
B4X:
AStreams.Initialize(Socket1.InputStream,Socket1.OutputStream,"Astreams")
The sending is done to unequal packages of about 8 KB
Unfortunately, the AStreams_Terminated and/or AStreams_DataCompleted events are never called.
B4X:
Sub AStreams_Terminated
    LogColor("END (Terminated)",Colors.Green )
End Sub
Sub AStreams_DataComplete
    LogColor("END (DataComplete)",Colors.Green )
End Sub

B4X:
Sub AStreams_NewData (Buffer() As Byte)
   Dim msg                As String
  Dim sf                   As StringFunctions
   sf.initialize
    msg = BytesToString(Buffer, 0, Buffer.Length, "ASCII")
    ric=sf.Left(msg,4)
    If ric="%PDF" Then
         ' OK
         LogColor("START PDF",Colors.Cyan)   
    End If
    If sf.InString(msg,Chr(10))>0 Then 
        ' this happens 4 or 5 times and not once
        LogColor("END PDF",Colors.Cyan)
    End If

Thanks in advance
 

nobbi59

Active Member
Licensed User
Longtime User
How do you know when your data is received completely?

This is why you should prefix every Message, you send from the PC with the Length of the following Message/Data. If youre sending it using B4j, you can use the built-in prefix mode by calling .Initialzeprefix . Otherwise you should create your own. just use the first 4 bytes for the length.

When receiving a new message, you check the first 4 bytes. Then you save it to a variable, then you check whether the received data length equals the length you saved before. If so, you're done. if not, wait until its done.

Terminated, as you can tell by the name, is not called when the receiving is done and i never saw the DataCompleted Event.
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
The transmissions of PDF files and short text messages come from a server developed in VB6, not B4J.
Despite numerous tests I could not add the 4 initial bytes that determine the length of the file.
B4X:
 '--- VB6 code     
Dim vIn As Long
Dim i As Integer
Dim Prefix As String
vIn = Len(T)
Dim vOut((LenB(vIn) - 1)) As Byte
For i = 0 To (LenB(vIn) - 1)
   vOut(i) = (Int(vIn / (2 ^ (8 * (LenB(vIn) - 1 - i))))) And ((2 ^ 8) - 1)
Next i
'For i = 0 To (LenB(vIn) - 1)
For i = (LenB(vIn) - 1) To 0 Step -1
   Debug.Print vOut(i)
   Prefix = Prefix & Chr$(vOut(i))
Next i
Debug.Print "prefix="; Prefix
T = Prefix & T
ServerSendData T

It would not be possible to use the instruction :
B4X:
AStreams.Initialize(Socket1.InputStream,Socket1.OutputStream,"Astreams")
instead of :
B4X:
AStreams.InitializePrefix(Socket1.InputStream, False, Socket1.OutputStream, "AStreams")
?
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
Upvote 0

nobbi59

Active Member
Licensed User
Longtime User
If you close the Server, the Astreams_Error event should be triggered.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It can take some time until the client detects it.

There are several ways to solve it:
1. Use a timer to ping the server every 500ms. It will help the client detect that the connection was broken.
2. Or:

B4X:
Sub AStreams_NewData (Buffer() As Byte)
 'your code here
 NewDataIndex = NewDataIndex + 1
 Dim MyIndex As Int = NewDataIndex
 Sleep(2000)
 If MyIndex = NewDataIndex Then
  'close connection
  If AStream.IsInitialized Then AStream.Close
 End If
NewDataIndex is a global int variable.
You should also increase it when a new connection is made.
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
Upvote 0
Top