【问题标题】:Android bluetooth socket data transfer and lifecycleAndroid 蓝牙套接字数据传输和生命周期
【发布时间】:2015-01-13 17:51:31
【问题描述】:

我目前正在尝试使用蓝牙在两个 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 发送,但这听起来不对。

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

【问题讨论】:

    标签: android android-bluetooth


    【解决方案1】:

    简单的答案是肯定的。您应该发送一个特定的令牌来表示 EOF。当您在蓝牙套接字上执行read() 操作时,如果有数据可供读取,它将立即返回一些数据,否则read() 调用将阻塞直到有一些数据, 一些 IO 异常发生(例如连接断开)。这就是为什么必须使用Threads 的原因,特别是对于蓝牙套接字读写操作。您尝试做的是依靠 BufferedReader 返回 -1 来表示“没有更多数据”。可悲的是,这不是它的工作方式。 -1 只会在某些 IO 异常或连接关闭的情况下发生。

    检测您的信息(即您的数据包)在哪里开始和结束,或者确实确定整个通信会话何时结束,是您在自己的应用程序协议(或者当然是现有协议)中处理的事情) 在套接字上工作。对于任何通过流式套接字工作的协议,这都是一个重要的概念。一个很好的例子是 HTTP,如您所知,它通常在 TCP 上使用。快速浏览一下 HTTP 将向您展示 (a) HTTP 协议如何使用标头告诉接收者整个 HTTP“消息”还需要多少字节,以及 (b)HTTP 标头如何也用于协商何时发送连接应该关闭。您不能做的是尝试使用套接字本身的方法来确定发送者何时完成了消息的写入。同样,如果一端要知道另一端想要关闭连接,则应通过应用程序协议进行协商。

    【讨论】:

    • 感谢您的洞察力。现在我心里清楚多了。您对要发送的特定令牌有什么建议吗?我对此有一些问题,尝试发送特定的 2 字节令牌但没有成功。进入快速而肮脏的模式并使用换行符,但这有点笨拙。
    • 如果您只是发送任意长度的简单文本字符串,也许您可​​以只使用换行符?或者,您可以设计一个更精细的数据包结构,例如以描述有效负载长度的标头字段开头。这归结为您希望执行的操作以及您尝试通过连接交换的内容。
    猜你喜欢
    • 1970-01-01
    • 2014-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 2012-05-01
    • 2022-11-18
    • 2013-04-27
    • 1970-01-01
    相关资源
    最近更新 更多