Android蓝牙套接字数据传输和生命周期

时间:2015-01-13 17:51:32

标签: android android-bluetooth

我目前正在尝试使用蓝牙在两个Android设备之间发送一些数据。我已经阅读了很多关于蓝牙传输,套接字和流的问题。到目前为止没有运气。 连接部分正在工作。我获取设备地址,然后使用以下命令打开连接:

BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(myOtherDeviceAdress);
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID.fromString(myUUID));
socket.connect();

然后尝试使用OutputStream

发送一些数据
OutputStream mmout=tmp.getOutputStream();
byte[] toSend="Hello World!".getBytes();
mmout.write(toSend);
mmout.flush();

在接收端:

mBluetoothServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("ccv_prototype", UUID.fromString(myUUID));
mBluetoothSocket = mBluetoothServerSocket.accept(3 * 1000);
InputStream is = mBluetoothSocket.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(is));

然后,尝试读取缓冲区的不同版本,目前:

int c;
StringBuilder response = new StringBuilder();
try {
    while ((c = r.read()) != -1) {
        //Since c is an integer, cast it to a char. If it isn't -1, it will be in the correct range of char.
        response.append((char) c);
    }
} catch (IOException e) {
    e.printStackTrace();
}
String result = response.toString();
Log.d("MyTag", "Received String: " + result);

我的问题是,如果我不关闭OutputStream,接收端永远不会收到EOF,但如果我添加mmout.close();,它会在它甚至有时间阅读邮件之前关闭我想发送。到目前为止,我唯一的想法是发送一个特定的令牌作为EOF,但这听起来不对。

我错过了什么? 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

简单的答案是肯定的。您应该发送一个特定的令牌来表示EOF。当您在蓝牙套接字上执行read()操作时,如果准备好要读取数据,它将立即返回一些数据,否则read()调用将阻止直到有一些数据,发生了一些IO异常(例如连接丢失)。这就是您必须使用Thread的原因,特别是对于蓝牙套接字读写操作。您尝试做的是依靠BufferedReader返回-1来表示"没有更多数据"。可悲的是,这不是它的工作原理。 -1只会在发生某些IO异常或连接关闭时发生。

检测您的信息(即您的数据包)的开始和结束位置,或确实确定整个通信会话何时结束,您可以在自己的应用程序协议中处理(或者当然是现有协议) )在套接字上工作。这是一个重要的概念,任何通过流套接字工作的协议。一个很好的例子就是HTTP,正如你所知,它通常用于TCP。快速查看HTTP将向您显示(a)HTTP协议如何使用标头告诉收件人整个HTTP"消息"还有多少字节,以及(b)HTTP标头如何也是如此用于在连接关闭时进行协商。您无法做的是尝试使用套接字本身上的方法来确定发件人何时完成邮件编写。同样,如果要知道另一端想要关闭连接,那么应该通过应用协议进行协商。