Wednesday, August 28, 2019

java - TCP server on android phone crashes at .accept()



I'm new to android but not to sockets. I have a GUI with a button that runs the UAVServer thread. When I click it, the server should listen for the client. The line of code...



Socket client = serverSocket.accept();


...Should block until a client connects. But it just crashes saying "Unfortunately, DroidUAV has stopped."




public class UAVServer extends Thread {

private String TAG = UAVServer.class.getSimpleName();

@Override
public void run() {
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(12345);
Log.d(TAG, "Fails at the next line of code");

Socket client = serverSocket.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


This seems pretty straight forward, why would it be crashing? Also how does android handle blocking ports, this might have something to do with it. If it was on the wifi, I figure it would be up to the router to unblock ports. But what if I was just on 4G?




NOTE: uses-permission android:name="android.permission.INTERNET"
is in my manifest file.



Edit:
I must be doing something wrong, because I just tried to make it run the client instead and it crashes on this line...



Socket s = new Socket("192.168.1.102",4444);



Edit:
Added errors...



FATAL EXCEPTION: main
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View$1.onClick(View.java:3071)
at android.view.View.performClick(View.java:3538)
at android.widget.CompoundButton.performClick(CompoundButton.java:103)
at android.view.View$PerformClick.run(View.java:14319)
at android.os.Handler.handleCallback(Handler.java:608)

at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:5099)
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:991)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:758)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)

at java.lang.reflect.Method.invoke(Method.java:511)
at android.view.View$1.onClick(View.java:3066)
... 12 more
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1190)
at libcore.io.BlockGuardOs.accept(BlockGuardOs.java:54)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:98)
at java.net.ServerSocket.implAccept(ServerSocket.java:202)
at java.net.ServerSocket.accept(ServerSocket.java:127)
at com.example.droiduav.UAVServer.run(UAVServer.java:19)

at com.example.droiduav.MainActivity.onToggleServer(MainActivity.java:31)
... 15 more

Answer



Well, the problem you are facing has to do with the following exception that can be seen in your LogCat trace:



Caused by: android.os.NetworkOnMainThreadException



What it means is pretty straightforward guessable from the name. Don't perform any Network code on the Main UI Thread. Solution: Start your own thread for that (see this Android Developer article).




Why?



Network code can take a "long time" (assume several seconds) to execute. If you would call all your network code on the main thread, it will freeze the UI in the mean time (this is - as one could guess - not really preferable and could and will result in ANR exceptions).



see also these questions as they are related to your problem:




No comments:

Post a Comment

hard drive - Leaving bad sectors in unformatted partition?

Laptop was acting really weird, and copy and seek times were really slow, so I decided to scan the hard drive surface. I have a couple hundr...