Giter VIP home page Giter VIP logo

Comments (7)

xmaihh avatar xmaihh commented on June 23, 2024

实现AbsStickPackageHelper接口,按照你自己的协议处理数据即可。

from android-serialport.

lucf1103 avatar lucf1103 commented on June 23, 2024

image
大佬,问下,这样写是不是就拆分了“AA” 打头数据的粘包问题

from android-serialport.

xmaihh avatar xmaihh commented on June 23, 2024

按照你之前的描述:“目前2种类型的数据,都是AA开头,第2位是对应长度,最后一位是合校验(2个类型的数据长度不一致)”

大致实现如此:

byte[] execute(InputStream is) {
    byte[] buffer = new byte[1024];
    int length = 0;
    boolean hasStartFlag = false; // 是否已经接收到协议头AA
    int dataLength = 0; // 数据长度
    int readCount; // 实际读取到的字节数
    while ((readCount = is.read(buffer, length, buffer.length - length)) > 0) {
        length += readCount;
        if (!hasStartFlag) { // 先找到协议头AA
            int startIndex = findStartFlag(buffer, length);
            if (startIndex >= 0) { // 找到了
                hasStartFlag = true;
                length -= startIndex;
            } else { // 没找到,丢弃全部数据
                length = 0;
            }
        } else { // 已经有协议头AA了
            if (length >= 2) { // 至少要有2个字节的长度信息
                dataLength = buffer[1] & 0xFF;
                if (length >= dataLength + 3) { // 数据区加上校验和共dataLength+2个字节,再加1个字节的校验和
                    if (checkSum(buffer, 2, dataLength + 2) == buffer[dataLength + 2]) { // 校验和正确
                        byte[] result = new byte[dataLength];
                        System.arraycopy(buffer, 2, result, 0, dataLength);
                        System.arraycopy(buffer, dataLength + 3, buffer, 0, length - (dataLength + 3));
                        length -= (dataLength + 3);
                        hasStartFlag = false;
                        return result; // 返回解析结果
                    } else { // 校验和错误,丢弃这个包
                        System.arraycopy(buffer, dataLength + 3, buffer, 0, length - (dataLength + 3));
                        length -= (dataLength + 3);
                        hasStartFlag = false;
                    }
                } else { // 数据还不够,继续读取
                    continue;
                }
            } else { // 长度信息还没有读完,继续读取
                continue;
            }
        }
    }
    return null; // 没有读到完整的数据包,返回null
}

int findStartFlag(byte[] buffer, int length) {
    for (int i = 0; i < length - 1; i++) {
        if (buffer[i] == (byte) 0xAA && buffer[i + 1] > 0) { // 协议头AA并且长度不为0
            return i;
        }
    }
    return -1;
}

int checkSum(byte[] buffer, int offset, int length) {
    int sum = 0;
    for (int i = offset; i < offset + length; i++) {
        sum += buffer[i] & 0xFF;
    }
    return sum & 0xFF;
}

from android-serialport.

lucf1103 avatar lucf1103 commented on June 23, 2024

能否留个联系方式,有偿解决。这边回传的result 是完整的带头和尾的吧?
写这个接口里是对的吧?
image

代码复制进去之后,部分参数没使用到,是没问题的吧?晚上去板子上测试..
image

from android-serialport.

pbaiyy avatar pbaiyy commented on June 23, 2024

按照你之前的描述:“目前2种类型的数据,都是AA开头,第2位是对应长度,最后一位是合校验(2个类型的数据长度不一致)”

大致实现如此:

byte[] execute(InputStream is) {
    byte[] buffer = new byte[1024];
    int length = 0;
    boolean hasStartFlag = false; // 是否已经接收到协议头AA
    int dataLength = 0; // 数据长度
    int readCount; // 实际读取到的字节数
    while ((readCount = is.read(buffer, length, buffer.length - length)) > 0) {
        length += readCount;
        if (!hasStartFlag) { // 先找到协议头AA
            int startIndex = findStartFlag(buffer, length);
            if (startIndex >= 0) { // 找到了
                hasStartFlag = true;
                length -= startIndex;
            } else { // 没找到,丢弃全部数据
                length = 0;
            }
        } else { // 已经有协议头AA了
            if (length >= 2) { // 至少要有2个字节的长度信息
                dataLength = buffer[1] & 0xFF;
                if (length >= dataLength + 3) { // 数据区加上校验和共dataLength+2个字节,再加1个字节的校验和
                    if (checkSum(buffer, 2, dataLength + 2) == buffer[dataLength + 2]) { // 校验和正确
                        byte[] result = new byte[dataLength];
                        System.arraycopy(buffer, 2, result, 0, dataLength);
                        System.arraycopy(buffer, dataLength + 3, buffer, 0, length - (dataLength + 3));
                        length -= (dataLength + 3);
                        hasStartFlag = false;
                        return result; // 返回解析结果
                    } else { // 校验和错误,丢弃这个包
                        System.arraycopy(buffer, dataLength + 3, buffer, 0, length - (dataLength + 3));
                        length -= (dataLength + 3);
                        hasStartFlag = false;
                    }
                } else { // 数据还不够,继续读取
                    continue;
                }
            } else { // 长度信息还没有读完,继续读取
                continue;
            }
        }
    }
    return null; // 没有读到完整的数据包,返回null
}

int findStartFlag(byte[] buffer, int length) {
    for (int i = 0; i < length - 1; i++) {
        if (buffer[i] == (byte) 0xAA && buffer[i + 1] > 0) { // 协议头AA并且长度不为0
            return i;
        }
    }
    return -1;
}

int checkSum(byte[] buffer, int offset, int length) {
    int sum = 0;
    for (int i = offset; i < offset + length; i++) {
        sum += buffer[i] & 0xFF;
    }
    return sum & 0xFF;
}

我把我原来在onDataReceived方法里面做处理的改为你提供的这种方式,但是命令处理的反应速度却变慢了。。比如我点击一个按钮,要等串口返回,原来在onDataReceived里处理,立马就能接收到,现在用这种方式处理,就变慢了,请问下有什么办法解决吗?

from android-serialport.

xmaihh avatar xmaihh commented on June 23, 2024

我提供给你的是代码是为了帮助理解,你需要根据自己的业务去实现。这段代码是在一个循环中不断地检查、拆解和校验数据包,这种方式可能会造成处理速度较慢,你可以考虑异步处理方式,将数据接收和处理过程分离,避免阻塞主线程。

from android-serialport.

pbaiyy avatar pbaiyy commented on June 23, 2024

我提供给你的是代码是为了帮助理解,你需要根据自己的业务去实现。这段代码是在一个循环中不断地检查、拆解和校验数据包,这种方式可能会造成处理速度较慢,你可以考虑异步处理方式,将数据接收和处理过程分离,避免阻塞主线程。

我想了下,这个粘包的,接收是在execute中接收,如果再把处理扔回到onDataReceived,那不是等于没做execute这个步骤吗?一时间想不到怎么把两个部分分开。或者说在execute和onDataReceived里,分别执行什么部分的业务好呢?这个优化有点没想明白。

from android-serialport.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.