通讯协议的数据封包,以及数据转义问题解决分析

最近在写树莓派和手机的蓝牙通讯的程序,为了确保数据传输的可靠性,找了不少方案,都建议将数据打包传输,所以的研究一下这方面的东西。

简单来说,为了保证数据传输的可靠性,传输数据的时候最好要把数据打包成一个明确头尾的数据包的形式进行传输,接收方通过识别包头,包尾确保整个数据的完整性。

这里面就涉及如何识别包头和包尾,以及如何保证包内的数据不会出现和包头包尾混淆的情况,也就是转义的问题了!

// bytes是未转义前数据
byte[] buf = new byte[bytes.length * 2]; // buf临时间文件,大小是bytes的2倍,防止转义后长度超过原来长度,最多不超过2倍!
while (i < bytes.length) {
    //转义
    byte aByte = bytes[i];
    switch (aByte) {
        case 0x02: //0x02是包头的识别字节,也就是如果原数据中有0x02这种字节,就要转义成0x1b0x17这两个字节
            buf[j] = 0x1b;
            buf[j + 1] = 0x17;
            j = j + 1;
            continue;
        case 0x03: //0x03是包尾的识别字节,也就是如果原数据中有0x03这种字节,就要转义成0x1b0x18这两个字节
            buf[j] = 0x1b;
            buf[j + 1] = 0x18;
            j = j + 1;
            continue;
        case 0x1b: //0x1b是转义的识别字节,也就是如果原数据中有0x1b这种字节,就要转义成0x1b0x19这两个字节
            buf[j] = 0x1b;
            buf[j + 1] = 0x19;
            j = j + 1;
            continue;
        default: //普通的字符字节加到buf
            buf[j] = aByte;
            i = i + 1;
    }
    j = j + 1;
}
byte[] bytes1 = new byte[j];
System.arraycopy(buf, 0, bytes1, 0, j);
return bytes1; //转义后的字节,一般比原来的长

简单来说0x02是包头识别字节,0x03是包尾识别字节,0x1b是转义识别字节,这3个识别字节其实可以任意选择

0x02=>0x1b0x17
0x03=>0x1b0x18
0x1b=>0x1b0x19