android - 蓝牙适配器 - 消息处理程序缓冲区限制

Hos*_*ari 2 java android buffer bluetooth

我正在使用本教程构建一个使用蓝牙进行连接的多人游戏:

https://developer.android.com/samples/BluetoothChat/index.html

由于我发送的是JSON格式的长串(如长度为5500+),因此消息处理程序方法不返回我发送的整个字符串,而是将它们拆分为989个字符长的字符串(其长度始终为989个字符).问题是,当我尝试解析JSON字符串时,显然会抛出错误,因为文本不完整.当我在控制台中打印出字符串时,它会将它们打印成多行,分割为989个字符.

另请注意,缓冲区长度设置为1024,但是当我增加限制时,结果将不会有所不同,并且它总是989个字符.

byte[] buffer = new byte[1024];
Run Code Online (Sandbox Code Playgroud)

知道发生了什么事吗?这是消息处理程序方法.请注意,从主机设备发送的消息看起来很好(它没有拆分),但是当客户端收到它时,它会分成多个字符串.

private static final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case BluetoothService.MESSAGE_STATE_CHANGE:
                switch (msg.arg1) {
                    case BluetoothService.STATE_CONNECTED:
                    case BluetoothService.STATE_CONNECTING:
                    case BluetoothService.STATE_LISTEN:
                    case BluetoothService.STATE_NONE:
                        break;
                }
                break;
            case BluetoothService.MESSAGE_WRITE:
                // BYTE LENGTH IS OK IN HERE!
                byte[] writeBuf = (byte[]) msg.obj;
                String writeMessage = new String(writeBuf);
                break;
            case BluetoothService.MESSAGE_READ:
                // BYTE LENGTH IS 1024 IN HERE!
                byte[] readBuf = (byte[]) msg.obj;
                message = new String(readBuf, 0, msg.arg1);
                break;
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

Bob*_*der 6

通过蓝牙套接字传递的数据被抽象为流,但在传输层被分成数据包,最大大小约为1000字节.在发送方,您可以获取输出流并写入5 KB的数据块,但传输层会在通过无线传输之前将其分成多个数据包.当接收器读取其输入流时,每次调用read()将返回一个数据包的数据.传输层不会重新组合数据包,您的代码需要这样做.这意味着您需要设计一些方案,例如包含消息长度的消息头,接收者在停止汇编数据包时可以知道该消息,并将完整的消息传递给消费处理.

BluetoothChat示例应用程序未解决此问题,因为它(静默地)假定所有聊天消息都小于数据包大小,因此不需要重新组装消息.