首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用WifiP2p连接通过套接字发送数据时App崩溃

使用WifiP2p连接通过套接字发送数据时App崩溃
EN

Stack Overflow用户
提问于 2019-03-27 22:25:28
回答 3查看 1.2K关注 0票数 0

应用程序在使用wifi p2p连接通过套接字发送数据时崩溃

我正在测试HTC_Desire_10 pro (运行Android6.0)和OPPO A83 (运行Android7.1.1)之间的一个简单聊天应用程序。我有相同的应用程序运行在这两台设备上。该应用程序首先打开wifi,然后开始发现用户单击事件的对等点。用户可以从动态生成的对等列表中选择要连接到的设备。这两种设备能够成功地连接起来。我可以发送一条短信从HTC到OPPO手机,但当我试图发送消息从OPPO手机,应用程序崩溃。

这是指定哪个设备将是主机或客户端的代码。

代码语言:javascript
复制
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的代码

代码语言:javascript
复制
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功能。

代码语言:javascript
复制
btnSend.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String msg = writeMsg.getText().toString();
        sendReceive.write(msg.getBytes());
    }
});

我使用android在USB调试模式下运行了这个应用程序,并从亚行logcat命令中获得了崩溃报告:

代码语言:javascript
复制
--------- 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

..。

有人能解释一下为什么这个应用会这样吗?我已经遍历了整个日志大约一个小时,我似乎找不到我的代码到底出了什么问题。任何帮助都将不胜感激。

关于你的。

EN

回答 3

Stack Overflow用户

发布于 2019-03-30 05:31:58

结果是,在套接字连接建立之前,write()方法试图写入套接字的outputStream。默认情况下,我禁用了“发送消息”按钮,然后使用AsyncTask在后台线程中设置套接字连接。一旦doInBackground()方法完成执行,它将调用onPostExecute(),然后使用socket.getInputStream()socket.getOutputStream()分别设置套接字的inputStreamoutputStream,并启用send按钮。send按钮有一个OnClickListener,它在单击事件上调用write()方法。

默认禁用发送消息按钮

代码语言:javascript
复制
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);
            }
        }
    });

服务器线程

代码语言:javascript
复制
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
        }
    }
}

客户端线程

代码语言:javascript
复制
    public class Client extends AsyncTask<String, Integer, Boolean> {
    Socket socket;
    String hostAdd;
    InputStream inputStream;
    OutputStream outputStream;

    public Client(InetAddress hostAddress) {
        hostAdd = hostAddress.getHostAddress();
        socket = new Socket();
    }

    @Override
    protected Boolean doInBackground(String... strings) {
        boolean result = false;
        try {
            socket.connect(new InetSocketAddress(hostAdd, 8888), 5000);
            result = true;
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
            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();
            }
            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
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2022-05-14 05:42:14

将您的写函数替换为:

代码语言:javascript
复制
public void write(final byte[] bytes)
{
    new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            try
            {
                outputStream.write(bytes);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }).start();
}
票数 0
EN

Stack Overflow用户

发布于 2019-12-12 13:11:41

我在ServerClass.start()ClientClass.start()方法上显示了错误,您对此做了什么?

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55387403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档