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;
    }

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

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值