java - BluetoothServerSocket 不从 accept() 返回

标签 java android sockets bluetooth serversocket

我正在尝试为学校的项目构建一个小的蓝牙-Android-App。

我是 Android 的新手(拿到手机才 2 天)。两周以来,我一直在笔记本电脑上进行 Android 编程实验。安装了带有 Android x86 (eeepc) 的 VirtualBox,因此我可以使用笔记本电脑的 BluetoothAdapter。模拟器不支持蓝牙而且速度很慢。这是关于项目...

问题/疑问: 蓝牙连接有 2 个设备 - 连接设备和监听设备。监听设备有一个 BluetoothServerSocket,它循环 accept() 方法直到 accept() 返回一个 BluetoothSocket。 在我的例子中,accept() 方法没有返回,所以我卡住了,应用程序卡住并出现黑屏,要求 mit 停止应用程序或只是等待。当我将超时传递给 accept() --> accept(10000) 时,我在超时后得到一个 IOException

监听器:

private class AcceptThread extends Thread {

    private BluetoothSocket tSocket;
    private BluetoothServerSocket bss = null;

    public void run() {
        try {
            Log.d(TAG, "erzeuge ServerSocket");
            bss = BluetoothAdapter.getDefaultAdapter().listenUsingInsecureRfcommWithServiceRecord("BluetoothChatInsecure", MainActivity.BT_UUID);
            Log.d(TAG, "ServerSocket OK");
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "Fehler Serversocket");
        }

        while (true)  {

            Log.d(TAG, "Versuche zu akzeptieren");
            try {
                Log.d(TAG, "Akzeptieren Anfang");
                tSocket = bss.accept(10000);
                //this line is never reached
                Log.d(TAG, "Akzeptieren Ende");

                if (tSocket != null){
                    //Hier wollen wir hin!
                    Log.d(TAG, "Verbindung akzeptiert");
                    ConnectedThread conThread = new ConnectedThread(tSocket);
                    conThread.run();
                    bss.close();
                    break;
                } else {
                    Log.e(TAG, "Fehler, keine Verbindung");
                }
            } catch (IOException e) {
                Log.e(TAG, "IOException währent accept-loop");
                //this exception is triggered every 10 sec, when the accept(10000) times out
                e.printStackTrace();
            }   
        }
        Log.i(TAG, "Acceptthread hat fertig");          
    }

}

连接设备:

try {
    socket = device.createInsecureRfcommSocketToServiceRecord(MainActivity.BT_UUID);

    outstr = socket.getOutputStream();
    instr = socket.getInputStream();

    ois = new ObjectInputStream(instr);
    oos = new ObjectOutputStream(outstr);

} catch (IOException e) {
    e.printStackTrace();
}

我在 stackoverflow 和其他一些论坛上阅读了很多关于这个主题的帖子,但我没有找到解决问题的方法。 抱歉我的英语不好,但我不是母语人士。

感谢您的帮助!

编辑:

我忘记写了,我用 2 台设备测试了该应用程序。我的笔记本电脑确实接受循环,而我使用手机并尝试连接。

最佳答案

这只是正常行为:accept() 将“等待”(阻塞)直到从另一台设备建立连接。然后它返回表示该连接的套接字以进行进一步的数据传输。

如您所见,超时通过 IOException 发出信号。 accept() 的约定是它从不返回 null,而是始终返回一个有效的套接字,或者失败并抛出异常。

因此,thejh 说你应该有一个专用线程来等待 accept() 中的连接是正确的。
accept() 返回一个新套接字时,您可能需要生成另一个线程来处理该套接字上的进一步通信,同时 accept() 线程循环等待下一个连接。

注意:您不能通过 Thread.interrupt() 关闭在 IO 中阻塞的线程(如在 accept() 中),但您必须关闭 ServerSocket 从另一个线程引发 IOException 以“唤醒”被阻塞的线程。

关于java - BluetoothServerSocket 不从 accept() 返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15734187/

相关文章:

Android - 全屏而不移动内容

javascript - 基于多个 ScrollView(s) 为单个 View 设置动画

C# - 使用 SSL 保护 `sockets`

c++ - C/C++ 字节顺序和 tcp 套接字

java - 如何配置 Spring Security 以使用自定义 AuthenticationManager 实现?

java - 如何在 JDL-Studio 中为 String 指定 MySQL 数据类型

java - Spring MVC - 将相同的对象从一个页面传输到另一个页面

java - Tomcat:如何创建类似于 HttpSessionListener 的 HttpRequestListener?

安卓工作室 : can't edit files after a while

java - ObjectInputStream 在 readObject() 期间永远阻塞