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

Android蓝牙套接字数据传输和生命周期,android,android-bluetooth,Android,Android Bluetooth,我目前正在尝试使用蓝牙在两台android设备之间发送一些数据。我读过很多关于蓝牙传输、套接字和流的问题。到目前为止没有任何运气。 连接部分正在工作。我获取设备地址,然后使用以下命令打开连接: BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(myOtherDeviceAdress); BluetoothSocket socket = device.createRfcommSocketToS

我目前正在尝试使用蓝牙在两台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,但这听起来并不正确

我错过了什么?
感谢您的帮助。

简单的答案是肯定的。您应该发送一个特定的令牌来表示EOF。在蓝牙套接字上执行
read()
操作时,如果有数据准备好读取,则会立即返回一些数据,否则
read()
调用将阻塞,直到出现一些数据,或者发生一些IO异常(例如,连接断开)。这就是为什么您必须使用
线程
s,尤其是蓝牙套接字读写操作。您试图做的是依靠
BufferedReader
返回-1来指示“不再有数据”。可悲的是,这不是它的工作原理。只有在IO异常或连接关闭的情况下,-1才会发生


检测信息(即数据包)的开始和结束位置,或者确定整个通信会话何时结束,是您自己在套接字上工作的应用程序协议(或者当然是现有协议)中处理的事情。这对于任何通过流式套接字工作的协议来说都是一个重要的概念。一个很好的例子是HTTP,如您所知,它通常通过TCP使用。快速查看HTTP将向您展示(a)HTTP协议如何使用头告诉收件人整个HTTP“消息”的预期字节数,以及(b)HTTP头如何也用于协商何时应关闭连接。您不能做的是尝试使用套接字本身的方法来确定发件人何时完成了消息的编写。类似地,如果一端意识到另一端想要关闭连接,则应通过应用程序协议进行协商。

感谢您的见解。现在在我的脑海里更清楚了。关于要发送的特定令牌,您有什么建议吗?我在这方面遇到了一些问题,试图发送一个特定的2字节令牌,但没有成功。在快速和肮脏的模式下,使用换行符,但这有点不公平。如果你只是发送任意长度的简单文本字符串,也许你可以使用换行符?或者,您可以设计更复杂的数据包结构,例如,它将以描述有效负载长度的报头字段开始。这可以归结为您希望做什么以及您试图通过连接交换什么。