基于Vert.x的自定义通信协议解析(粘包、拆包)

公司服务于农业物联网行业,由我负责开发与.net代理服务(代理控制器)的通信,根据前期的建设情况,选择Socket自由协议通信,报文投标首字节68H、2字节长度、68H,末尾1字节校验位+16H。

我用Vertx创建TCP client监听代理服务,实现通信。处理器接收buffer,我需要对buffer进行解包,由于是自由协议,无法自动实现粘包、拆包的处理,于是自己写了部分代码,也就是本文的重点。


/**
 * description: BufferWrapper <br>
 * date: 2020/6/9 8:50 <br>
 * author: jiasp <br>
 * version: 1.0 <br>
 */
public class BufferWrapper {

    private Buffer buffer;
    private Buffer netxtBuffer;
    private Buffer tempBuffer;

    public boolean hasNextBuffer(){
        if(buffer == null)return false;
        if(buffer.length()>=(buffer.getUnsignedShort(1)+6)){
            return true;
        }else {
            //记录
            tempBuffer = buffer;
            return false;
        }
    }

    public Buffer nextBuffer(){
        int len = buffer.getUnsignedShort(1);
        //System.out.println("nextBuffer:len is "+len);
        if(buffer.length()>(len+6)){
            netxtBuffer = buffer.getBuffer(0, buffer.getUnsignedShort(1) + 6);
            //System.out.println("OrginBuffer is "+ByteUtils.byteToHex(buffer.getBytes()));
            buffer = buffer.getBuffer(buffer.getUnsignedShort(1) + 6,buffer.length());
            //System.out.println("RemainBuffer is "+ByteUtils.byteToHex(buffer.getBytes()));
            return netxtBuffer;
        }else if(buffer.length()==(len+6)){
           netxtBuffer = buffer;
           buffer = null;
           return netxtBuffer;
        }else if(buffer.length()<(len+6)){
            netxtBuffer = null;
            System.out.println("this is halfBuffer that"+ByteUtils.byteToHex(buffer.getBytes()));
            return netxtBuffer;
        }
        return netxtBuffer;
    }


    public Buffer getHalfBuffer(){
        return tempBuffer;
    }


    public BufferWrapper(Buffer buffer){
        this.buffer = buffer;
    }


    public BufferWrapper(Buffer buffer,Buffer halfBuffer){
        this.buffer = halfBuffer.appendBuffer(buffer);
    }
}

主要实现了一个buffer的包装类,然后接收buffer之后创建一个BufferWrapper对象,然后处理粘包和拆包,剩下的半包需要在调用类中用对象缓存,便于下一次的buffer进行append操作。

实际效果还可以,但是考虑到EventLoop线程是异步非阻塞的,假如待解包较多仍然会导致线程阻塞(默认2秒),因此,建议此部分最好是先接消息队列或者Redis(订阅模式),防止EventLoop线程阻塞,最后慢慢解析。我这边数据量不大暂时就是同步处理的,笔记本8个线程的话,几千个并发还能应付,后期考虑将代码异步化处理。

未完待续....

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值