Android Question SocketServer streams

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Hi
I did a server who connects with a client, using a service. After successfully connecting, I am trying to use directly the ServerSocket.InputStream to read data (and would like to use ServerSocket.OutputStream to write). Actually I have previously assigned it to a variable of type InputStream. I know that there are many examples using AsyncStreamObjects for this task. My question is relative to this subject and I would like to know my mistake. (If impossible or incorrect to use Input/Output streams, I will use AsyncStreams). Thanks in advance.
The service code and log output are:
B4X:
#Region Service Attributes
#StartAtBoot: False
#ExcludeFromLibrary: True
#End Region
Sub Process_Globals
  Dim ServerS As ServerSocket
  Dim nPort As Int : nPort=10250
  Dim ClientIp,MyIp As String
  Dim Istream As InputStream  '<<<<<< variable used for Reading bytes
  Dim Ostream As OutputStream
  Dim Buff(128) As Byte
  Dim Command,Answer As String
  Dim Conv As ByteConverter
End Sub

Sub Service_Create
   ServerS.Initialize(nPort,"ServerEvents")
End Sub

Sub Service_Start (StartingIntent As Intent)
  ServerS.Listen
End Sub

Sub Service_Destroy
  ServerS.Close
End Sub

Sub ServerEvents_NewConnection (Successful As Boolean, NewSocket As Socket)
  If Successful Then
      Istream=NewSocket.InputStream  '<<<<<
      Ostream=NewSocket.OutputStream
 
      StartReceiver

  Else
      Msgbox(LastException.Message, "Error connecting")
  End If
   'ServerS.Listen ' not necessary Continue listening to new incoming connections (but ininfluent)
End Sub

Sub StartReceiver
    Dim count As Int
    count=0
    Do While count=0
       count=Istream.BytesAvailable
    Loop
    Log("BytesAvailable:" & count)
    Istream.ReadBytes(Buff,0,count)  '<<<<<<<<<<<<<<< here the error
 End Sub
The debug log is:
PackageAdded: package:b4a.example
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (starter) Start **

BytesAvailable:2
starter_startreceiver (B4A line: 78)
Istream.ReadBytes(Buff,0,count)
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
at libcore.io.IoBridge.recvfrom(IoBridge.java:503)
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
at anywheresoftware.b4a.objects.streams.File$InputStreamWrapper.ReadBytes(File.java:406)
at b4a.example.starter._startreceiver(starter.java:393)
at b4a.example.starter._serverevents_newconnection(starter.java:247)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
at anywheresoftware.b4a.BA$3.run(BA.java:334)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4514)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
 

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Hi. I am not using AsyncStreams. I know that I can do the job with AsyncStreams, but I would like to know why my code is wrong.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Hi. I am not using AsyncStreams. I know that I can do the job with AsyncStreams, but I would like to know why my code is wrong.
The returned error is:
android.os.NetworkOnMainThreadException

That means you try to access a network in the main thread, which is not recommended under Android (and other OS as well) because that can freeze the UI and raise an ApplicationNotResponding error after a few seconds. Use only asynchronous functions. There exists a mean to enable network calls from the main thread but this is stupid and goes against the Google recommandations.
 
Upvote 0
Top