Java 如何确保在关闭Android BluetoothSocket之前发送所有数据

Java 如何确保在关闭Android BluetoothSocket之前发送所有数据,java,android,bluetooth,android-bluetooth,bluetooth-socket,Java,Android,Bluetooth,Android Bluetooth,Bluetooth Socket,我正在制作一个android应用程序,可以通过蓝牙在手机之间进行通信。为了节省电池,我不想一直保持蓝牙连接打开。所以每次我要发送消息时,我都会打开一个连接,发送消息,刷新,然后关闭 我的问题是,有时,但并非总是,接收电话给我臭名昭著的“java.io.IOException:bt套接字关闭,读取返回:-1”。我看到美国 BluetoothSocket是线程安全的。特别是,close()总是会立即中止正在进行的操作并关闭套接字 然而,大会指出: 完成BluetoothSocket后,始终调用clo

我正在制作一个android应用程序,可以通过蓝牙在手机之间进行通信。为了节省电池,我不想一直保持蓝牙连接打开。所以每次我要发送消息时,我都会打开一个连接,发送消息,刷新,然后关闭

我的问题是,有时,但并非总是,接收电话给我臭名昭著的“java.io.IOException:bt套接字关闭,读取返回:-1”。我看到美国

BluetoothSocket是线程安全的。特别是,close()总是会立即中止正在进行的操作并关闭套接字

然而,大会指出:

完成BluetoothSocket后,始终调用close()。这样做将立即关闭连接的套接字并释放所有相关的内部资源

这是我发送消息的线程的摘录

            localSocket = device.createRfcommSocketToServiceRecord(MY_UUIDS[0]);
            localSocket.connect();
            Log.d(TAG, "Correctly Connected on " + MY_UUIDS[0]);
            OutputStream rawOutputStream = localSocket.getOutputStream();
            ObjectOutputStream messageOutputStream = new ObjectOutputStream(rawOutputStream);
            // Actually send the message
            messageOutputStream.writeObject(message);
            messageOutputStream.flush();
            rawOutputStream.flush();

            messageOutputStream.close();
            rawOutputStream.close();
            localSocket.close();
下面是我接受传入连接的线程的摘录:

                    InputStream rawInputStream = socket.getInputStream();
                    ObjectInputStream messageInputStream = new ObjectInputStream(rawInputStream);
                    BluetoothMessage joinMessage = (BluetoothMessage) messageInputStream.readObject();
                    BluetoothDevice device = socket.getRemoteDevice();
                    messageInputStream.close();
                    rawInputStream.close();
                    socket.close();
                    socket = null;
我意识到刷新和关闭是多余的,但事实是,有时由于硬件延迟,在发送所有消息之前,套接字在发送端关闭

我可以确认,无论我以多快的速度发送消息,每次都能完美地收到所有消息……如果我不关闭插座。但是,我知道关闭插座始终是最佳做法


那么,我如何确保在调用socket.close()之前发送所有消息?显然,flush()和stream close()没有做它们应该做的事情,否则,无论何时调用socket.close(),消息都会被完全发送。

首先,我认为你的第一个假设并不完全正确。如果这两个设备将持续通信,那么实际上保持连接打开可能会更有效

但是关于您的问题,确实有时候,当抛出IOException时,传入的字节可能没有被完全读取

确保的唯一方法是实施某种协议,其中:

  • 从一个设备写入数据
  • 从远程设备读取它
  • 用远程设备发出的某种“确认”进行回复,以确认您的数据已被完全读取
  • 只有在收到“确认”后才能关闭插座

  • 您不需要任何刷新,只需要关闭对象输出流。很难相信
    close()。这在实践中是真的吗?是的,这就是我最终要做的。在应用程序中,我可能有多达七台设备与服务器设备通信,因此我排除了因电池原因而保持连接打开的可能性。我担心ack方法不起作用,因为远程设备在发送ack后需要关闭套接字,这可能会导致与原始消息发送相同的问题。所以,为了解决这个问题,我让远程设备调用read()返回负一,直到发生异常,知道第一个设备何时关闭了它的套接字。