SOCKET/串口通信粘包问题处理,附带详细代码

UDP TCP或者串口通信中有可能会出现粘包问题。具体解决办法有以下几种
1.自定义包体格式包含包头+包体长度
2.加大读取缓冲区buffer

本文介绍第一种方法的
socket通信中我们一般开启一个线程然后死循环的读取其中的信息

我们定好协议格式如下十六进制表示
A3A4+长度两字节+json
其中A3A4为协议头 json是我们需要的具体数据

我们就可以固定的先读取4个字节获取完整包长度再继续读取

                   byte[] temBuffer = new byte[4];
                    if (mInputStream == null) {
    
    
                        continue;
                    }
                    int ret = mInputStream.read(temBuffer);
                    if (ret > 0) {
    
    
                        byte[] msg = null;
                        //收到一条新命令为0XA3 0XA4开头的
                        if (temBuffer[0] == (byte) 0xA3 && temBuffer[1] == (byte) 0xA4) {
    
    
                            //计算命令长度 即2 3字节组合成Int
                            int cmdSize = ConvertUtilsPlus.getIntFromBytes(temBuffer[2], temBuffer[3]);
                            int bodyLength = 4+ cmdSize;//计算出中长度
                            msg = new byte[bodyLength];//申明本次接收一个完整数据需要的容量
                            int recLength = ret;//记录当前已接收数据的长度
                            int errorCount = 0;//记录错误次数
                            System.arraycopy(temBuffer, 0, msg, 0, recLength);//第一包无脑丢进数组中
                            //如果本次读取到的数据小于总长度那么继续read
                            while (recLength < bodyLength && errorCount < 10) {
    
    
                                byte[] temp = new byte[bodyLength - recLength];
                                int rec = mInputStream.read(temp);
                                if (rec <= 0) {
    
    
                                    errorCount++;
                                    continue;
                                }
                                //复制读取的数据到数组中
                                System.arraycopy(temp, 0, msg, recLength, rec);
                                recLength += rec;
                            }
                        }
                        //没有新消息继续循环
                        if (msg == null) continue;

getIntFromBytes方法如下

  public static int getIntFromBytes(byte low_h, byte low_l) {
    
    
        return  (low_h & 0xff) << 8 | low_l & 0xff;
    }

以上方法各位多看看注释应该能理解透彻

猜你喜欢

转载自blog.csdn.net/qq910689331/article/details/107733632