mina框架tcpt通讯接收数据断包粘包处理
Posted wangxg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mina框架tcpt通讯接收数据断包粘包处理相关的知识,希望对你有一定的参考价值。
用mina做基于tcp,udp有通讯有段时间了,一直对编码解码不是很熟悉,这次做项目的时候碰到了断包情况,贴一下解决过程,
我接受数据格式如下图所示:
unit32为c++中数据类型,代表4个字节,由上图可以看出第二个参数为数据长度
protected boolean doDecode(iosession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { in.order(ByteOrder.LITTLE_ENDIAN);//c++中默认读取数据是这个模式 int remaining = in.remaining(); if (remaining > 0) { in.mark();// 标记当前位置,以便reset int head = in.getInt();//消息头对应上图0x0 int length = in.getInt();//数据长度 if (length > remaining) {// 如果消息内容不够,则重置,相当于不读取size System.out.println("断包了, left=" + in.remaining()+ " length=" + length); in.reset(); return false;// 接收新数据,以拼凑成完整数据 此时断掉的前半部分数据仍在缓冲区中等待读取 } else {//数据完整,封住新的IoBuffer中传给messageReceived方法处理 byte[] bytes = new byte[length - 8];//获取数据长度时已经读取了八个字节,在这里去掉 in.get(bytes); IoBuffer buffer = IoBuffer.allocate(length); buffer.putInt(head); //把刚才读取到的数据重新放入buffer中 buffer.putInt(length); buffer.put(bytes); buffer.flip(); out.write(buffer); if (in.remaining() > 0) {// 如果读取内容后还粘了包,就让父类再给一次,进行下一次解析 // System.out.println("package left="+in.remaining()+" data="+in.toString()); } return true;// 这里有两种情况1:没数据了,那么就结束当前调用,有数据就再次调用 } } return false;// 处理成功,让父类进行接收下个包 }
中间遇到各种坑,总的来说还是对IoBuffer和mina框架的理解不够深入,记录下引以为戒........
以上是关于mina框架tcpt通讯接收数据断包粘包处理的主要内容,如果未能解决你的问题,请参考以下文章