App crashes while sending data over a socket using wifi p2p connection
I am testing a simple chat application between HTC_Desire_10 pro (running Android 6.0) and OPPO A83 (running Android 7.1.1). I have the same app running on the two devices. The app first turns wifi on, then starts discovering peers on a users click event. The user can choose the device they want to connect to from a dynamically generated peer list. The two devices are able to connect successfully. I am able to send a text message from the HTC to OPPO phone but when I try to send a message from the OPPO phone, the app crashes.
This is the code that assigns which device will be the host or client
WifiP2pManager.ConnectionInfoListener connectionInfoListener = new WifiP2pManager.ConnectionInfoListener() {
@Override
public void onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo) {
final InetAddress groupOwnerAddress = wifiP2pInfo.groupOwnerAddress;
if(wifiP2pInfo.groupFormed&&wifiP2pInfo.isGroupOwner) {
ConnectionStatus.setText("Host");
serverClass = new ServerClass();
serverClass.start();
} else if(wifiP2pInfo.groupFormed) {
ConnectionStatus.setText("Client");
clientClass = new ClientClass(groupOwnerAddress);
clientClass.start();
}
}
};
And this is the code for the ServerThread, ClientThread and SendRecieveThread
public class ServerClass extends Thread{
Socket socket;
ServerSocket serverSocket;
@Override
public void run() {
try {
serverSocket = new ServerSocket(8888);
socket = serverSocket.accept();
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class SendReceive extends Thread {
private Socket socket;
private InputStream inputStream;
private OutputStream outputStream;
public SendReceive(Socket skt) {
socket = skt;
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (socket!=null) {
try {
bytes = inputStream.read(buffer);
if(bytes>0) {
handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] bytes) {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ClientClass extends Thread {
Socket socket;
String hostAdd;
public ClientClass(InetAddress hostAddress) {
hostAdd = hostAddress.getHostAddress();
socket = new Socket();
}
@Override
public void run() {
try {
socket.connect(new InetSocketAddress(hostAdd, 8888),1000);
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The SendRecieve functionality gets invoked when a user clicks a send message button.
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = writeMsg.getText().toString();
sendReceive.write(msg.getBytes());
}
});
I've run the app in USB-debugging mode using android studio and obtained the crash report from the adb logcat command:
--------- beginning of crash
03-27 22:16:54.115 6904 6904 E AndroidRuntime: FATAL EXCEPTION: main
03-27 22:16:54.115 6904 6904 E AndroidRuntime: Process: june.androidapps.clatt, PID: 6904
03-27 22:16:54.115 6904 6904 E AndroidRuntime: android.os.NetworkOnMainThreadException
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1318)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at java.net.SocketOutputStream.write(SocketOutputStream.java:145)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at june.androidapps.clatt.MainActivity$SendReceive.write(MainActivity.java:264)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at june.androidapps.clatt.MainActivity$5.onClick(MainActivity.java:135)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at android.view.View.performClick(View.java:5773)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at android.view.View$PerformClick.run(View.java:23035)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:836)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:103)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at android.os.Looper.loop(Looper.java:232)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6802)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1103)
03-27 22:16:54.115 6904 6904 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
03-27 22:17:06.089 7393 7393 E AndroidRuntime: FATAL EXCEPTION: main
...
Can anyone please explain why the app behaves this way? I have gone through the entire logs for about an hour and I cant seem to find what's exactly going wrong in my code. Any help will be appreciated.
with regards.
my is showing error on
ServerClass.start()
andClientClass.start()
method, what did you do with this?Turns out the
write()
method was trying to write to the sockets'outputStream
before the socket connection was set up. I disabled the send message button by default, then usedAsyncTask
to setup the socket connection in a background thread. Once thedoInBackground()
method finishes executing it makes a call toonPostExecute()
which in turn usessocket.getInputStream()
andsocket.getOutputStream()
to setup the sockets'inputStream
andoutputStream
respectively and also enables the send message button. The send message button has aOnClickListener
which makes a call to thewrite()
method on a click event.Disable send message button by default
Server Thread
Client Thread