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

时间:2017-06-08 16:19:38

标签: java android bluetooth android-bluetooth bluetooth-socket

我正在制作一款能够通过蓝牙在手机之间进行通信的Android应用。为了节省电池,我想不要一直打开蓝牙连接。因此,每次我要发送消息时,我都会打开一个连接,发送消息,刷新,然后关闭。

我的问题是有时,但并非总是如此,接收电话给我臭名昭着的“java.io.IOException:bt socket closed,read return:-1”。我看到BluetoothSocket documentation个州

  

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

然而,一般Bluetooth page州:

  

完成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(),都会完全发送消息。

1 个答案:

答案 0 :(得分:0)

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

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

确保实现某种协议的唯一方法是:

  1. 从一台设备写入数据
  2. 从远程设备读取
  3. 从远程设备回复某种“确认”以确认您的数据已被完全读取。
  4. 只有在收到“确认”后才关闭套接字。