使用wifi p2p连接通过套接字发送数据时,应用程序崩溃
我正在测试HTC_Desire_10 pro(运行Android 6.0)和OPPO A83(运行Android 7.1.1)之间的简单聊天应用程序。 我在两个设备上运行相同的应用程序。该应用程序首先打开wifi,然后开始发现对等端 在用户点击事件上。用户可以从动态生成的中选择要连接的设备 同行名单。 这两个设备能够成功连接。我可以从HTC向OPPO手机发送短信 但是当我尝试从OPPO手机发送消息时,应用程序崩溃了。
这是用于指定将哪个设备作为主机或客户端的代码
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();
}
}
};
这是ServerThread,ClientThread和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();
}
}
}
当用户单击“发送消息”按钮时,将调用SendRecieve功能。
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = writeMsg.getText().toString();
sendReceive.write(msg.getBytes());
}
});
我已经使用android studio在USB调试模式下运行了该应用程序,并从adb logcat命令获取了崩溃报告:
--------- 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
...
您可以在此处查看完整的日志 https://drive.google.com/file/d/1CfKU5x2dQgkGBKHTvMywaNfPtMdCNEXG/view
任何人都可以解释为什么该应用程序具有这种行为吗?我已经浏览了整个日志约 一个小时,我似乎无法找到代码中到底出了什么问题。 任何帮助将不胜感激。
问候。
答案 0 :(得分:0)
在建立套接字连接之前,发现write()
方法试图写入套接字的outputStream
。我默认禁用发送消息按钮,然后使用AsyncTask
在后台线程中设置套接字连接。 doInBackground()
方法执行完毕后,将调用onPostExecute()
,后者依次使用socket.getInputStream()
和socket.getOutputStream()
来设置套接字的inputStream
和{{1} },并同时启用“发送消息”按钮。发送消息按钮具有一个outputStream
,可在点击事件中调用OnClickListener
方法。
默认情况下禁用发送消息按钮
write()
服务器线程
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = writeMsg.getText().toString();
byte[] bytes =msg.getBytes();
btnSend.setVisibility(View.INVISIBLE);
if(userType.equals("server")) {
serverClass.writeData(bytes);
} else {
clientClass.writeData(bytes);
}
}
});
客户端线程
public class Server extends AsyncTask<String, Integer, Boolean> {
Socket socket;
ServerSocket serverSocket;
InputStream inputStream;
OutputStream outputStream;
@Override
protected Boolean doInBackground(String... strings) {
boolean result = true;
try {
serverSocket = new ServerSocket(8888);
socket = serverSocket.accept();
} catch (IOException e) {
result = false;
e.printStackTrace();
}
return result;
}
public void writeData(final byte[] bytes) {
new Thread(new Runnable() {
@Override
public void run() {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Boolean result) {
if(result) {
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
//listener
new Thread(new Runnable(){
public void run() {
byte[] buffer = new byte[1024];
int x;
while (socket!=null) {
try {
x = inputStream.read(buffer);
if(x>0) {
handler.obtainMessage(MESSAGE_READ,x,-1,buffer).sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
} else {
Toast.makeText(getApplicationContext(),"could not create sockets",Toast.LENGTH_SHORT).show();
//restart socket assignment process
}
}
}
答案 1 :(得分:0)
我在ClientClass.start()
和{{1}}方法上显示错误,您对此做了什么?