蓝牙SPP收到一些包帧会丢失还是? [英] Bluetooth SPP receive some the package frame can lost or?

查看:14
本文介绍了蓝牙SPP收到一些包帧会丢失还是?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用android示例代码进行修改.只想收包裹但是,我的代码只在这里修改

I use android sample code to modify. Only want to receive package but, my code only modify here

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MESSAGE_STATE_CHANGE:
            if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
            switch (msg.arg1) {
            case BluetoothChatService.STATE_CONNECTED:
                mTitle.setText(R.string.title_connected_to);
                mTitle.append(mConnectedDeviceName);
                mConversationArrayAdapter.clear();
                break;
            case BluetoothChatService.STATE_CONNECTING:
                mTitle.setText(R.string.title_connecting);
                break;
            case BluetoothChatService.STATE_LISTEN:
            case BluetoothChatService.STATE_NONE:
                mTitle.setText(R.string.title_not_connected);
                break;
            }
            break;
        case MESSAGE_WRITE:
            byte[] writeBuf = (byte[]) msg.obj;
            // construct a string from the buffer
            String writeMessage = new String(writeBuf);
            mConversationArrayAdapter.add(writeMessage);
            break;
        case MESSAGE_READ:

            byte[] readBuf = (byte[]) msg.obj;
            // construct a string from the valid bytes in the buffer
            //String readMessage = new String(readBuf, 0, msg.arg1);
            //String readMessage = BytesTrans_fill.bytesToHexString(readBuf);
            Log.d("read", BytesTrans.bytes2HexString(readBuf,msg.arg1));
            String readMessage = BytesTrans.bytes2HexString(readBuf,msg.arg1);
            ppV.setText(ppV.getText().toString() + readMessage + "★");
            break;
        case MESSAGE_DEVICE_NAME:
            // save the connected device's name
            mConnectedDeviceName = msg.getData().getString(
                    DEVICE_NAME);
            Toast.makeText(getApplicationContext(), "Connected to "
                           + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
            break;
        case MESSAGE_TOAST:
            Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
                           Toast.LENGTH_SHORT).show();
            break;
        }
    }
};

和蓝牙聊天服务

    public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");

        byte[] buffer = new byte[1024];

        int bytes;

        // Keep listening to the InputStream while connected
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                break;
            }
        }
    }

并添加此功能

package com.example.android.BluetoothChat;

public class BytesTrans {
    public static String byte2HexString(byte b) {
        String ret = "";
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase()  + " ";
        return ret;
    }

    public static String bytes2HexString(byte[] b, int count) {
        String ret = "";
        for (int i = 0; i < count; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase() + " ";
        }
        return ret;
    }
    /*public static String String2byte(String b)
    {
        String[] ttt;
        for (int i = 0; i < b.length(); i++)
        {
            for (int j= i; j<=i+1; j++)
            {
                ttt[i] = b;
            }

        }           

        String ttmp = "";
        String tmp = "";





        ret += tmp;
    }*/
    public static int hexToTen(String b) {
        int D2 = Integer.parseInt(b,16);


        return D2;
        }
    }

但是这个程序有时甚至不显示在我的发送包的框架中

but this program to show sometime not even to my send package's frame

我发送这样的包裹:

aa0721082000120214093439000000000000000000000000000000000000000000297c0fe6b

aa07210820001202140934390000000000000000000000000000000000000000000297c0fe6b

但有时会收到包裹:

aa000297c0fe6b021314524700000000000000000000000000000000000000000297c0fe6b

aa000297c0fe6b02131452470000000000000000000000000000000000000000000297c0fe6b

如何更改我的代码以接收完整包的框架

how can I to change my code to receive complete package's frame

推荐答案

您尚未显示任何蓝牙接口代码.但是,如果这在很大程度上基于 BluetoothChat 示例,那么 BluetoothChat 示例就存在一个简单的问题:基本上,当从蓝牙套接字生成 read() 并放入字节数组,该数组引用使用 Handler 发送到 UI,正如您所做的那样.实际问题是,如果使用 BluetoothChat 示例以比打字速度更快的速度接收数据,那么您会开始看到字符丢失或变得混乱,因为随后的 read() 被覆盖数组,而 UI 仍在读取数组以提取收到的最后一组字符.

You haven't shown any of your Bluetooth interface code. However, if this is based heavily on the BluetoothChat example, then there is a simple problem with the BluetoothChat example as it stands: Basically, when a read() is made from the Bluetooth socket and put into a byte array, that array reference is sent across to the UI using a Handler, as you are doing. The actual problem is that if the BluetoothChat example is used to receive data at a speed of anything faster than typing rate, then you start to see characters go missing or become jumbled because a subsequent read() is overwriting the array while the UI is still reading the array to extract the last bunch of characters received.

因此,如果您的 MESSAGE_WRITE 对象包含对要进行套接字 read() 调用的数组的引用,那么这可能就是您丢失字符的原因.因此,尝试在 Message 中使用 Arrays.copyOf() 发送数组的副本.或者,也许您可​​以使用循环缓冲区安排.

So, if your MESSAGE_WRITE object contains a reference to the array you're making socket read() calls into, then this is possibly why you're losing characters. Therefore, try sending a copy of the array, using Arrays.copyOf(), in the Message. Or, perhaps there's a circular buffer arrangement you could use.

当我使用 BluetoothChat 示例作为我项目的基础时,我遇到了这个问题.我个人为解决这个问题(并消除复制缓冲区等的需要)所做的是实现一种机制,我将告诉蓝牙连接线程(包含阻塞套接字 .read() 的线程)),通过方法调用,我期望响应的字节数(幸运的是,我正在处理的协议允许知道响应长度).然后,连接线程仅在收到完整响应时发送 Message,而不是将多个带有响应片段的 Message 发送到 UI.

I had exactly this problem when I used the BluetoothChat example as the basis for my project. What I personally did to get around the problem (and to eliminate the need for copying buffers, etc.) was to implement a mechanism whereby I would tell the Bluetooth connection thread (the thread that contains the blocking socket .read()), by means of a method call, how many bytes I expect the response to be (fortunately, the protocol I'm dealing with allows the response length to be known). The connection thread then only sends a Message when the complete response is received, instead of sending several Messages with fragments of the response to the UI.

这篇关于蓝牙SPP收到一些包帧会丢失还是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆