如何确保在关闭之前发送所有数据 Android BluetoothSocket
How to ensure all data is sent before closing Android BluetoothSocket
我正在制作一个 android 应用程序,它将通过蓝牙在 phone 之间进行通信。为了节省电池,我想避免一直打开蓝牙连接。所以每次我要发送消息时,我都会打开一个连接,发送消息,刷新,然后关闭。
我的问题是有时,但并非总是如此,接收phone给我臭名昭著的"java.io.IOException: bt socket closed, read return: -1"。我看到 BluetoothSocket documentation 表示
BluetoothSocket is thread safe. In particular, close() will always immediately abort ongoing operations and close the socket.
然而,一般Bluetooth page指出:
When you're done with your BluetoothSocket, always call close(). Doing so will immediately close the connected socket and release all related internal resources.
这是我发送消息的线程的摘录。
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() 和流 close()' s 没有做他们应该做的,否则,无论我何时调用 socket.close().
,消息都会被完全发送
首先,我想说你的第一个假设并不完全正确。如果这两个设备要不断通信,实际保持连接打开可能会更有效。
但是关于你的问题,确实有时在抛出 IOException 时传入的字节可能没有被完全读取。
确保的唯一方法是实施某种协议,您可以:
- 从一台设备写入数据
- 从远程设备读取
- 使用来自远程设备的某种 "ack" 回复以确认您的数据已被完整读取。
- 仅在收到 "ack" 后关闭套接字。
我正在制作一个 android 应用程序,它将通过蓝牙在 phone 之间进行通信。为了节省电池,我想避免一直打开蓝牙连接。所以每次我要发送消息时,我都会打开一个连接,发送消息,刷新,然后关闭。
我的问题是有时,但并非总是如此,接收phone给我臭名昭著的"java.io.IOException: bt socket closed, read return: -1"。我看到 BluetoothSocket documentation 表示
BluetoothSocket is thread safe. In particular, close() will always immediately abort ongoing operations and close the socket.
然而,一般Bluetooth page指出:
When you're done with your BluetoothSocket, always call close(). Doing so will immediately close the connected socket and release all related internal resources.
这是我发送消息的线程的摘录。
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() 和流 close()' s 没有做他们应该做的,否则,无论我何时调用 socket.close().
,消息都会被完全发送首先,我想说你的第一个假设并不完全正确。如果这两个设备要不断通信,实际保持连接打开可能会更有效。
但是关于你的问题,确实有时在抛出 IOException 时传入的字节可能没有被完全读取。
确保的唯一方法是实施某种协议,您可以:
- 从一台设备写入数据
- 从远程设备读取
- 使用来自远程设备的某种 "ack" 回复以确认您的数据已被完整读取。
- 仅在收到 "ack" 后关闭套接字。