MINA通信deCode实现

原创 2014年06月13日 09:21:17
public class SocketServerDecoder extends CumulativeProtocolDecoder {
private static final Logger log = Logger.getLogger(SocketServerDecoder.class);
public static final boolean ifPrintDebugInfo=false;
private Charset charset =null;
private static final String ATTRIBUTE_NAME="HelperMsgInfo";

public SocketServerDecoder(Charset charset) {
this.charset=charset;
log.debug("Server端#SocketServerDecoder构造方法,当前线程:"+Thread.currentThread().getId());
}

@Override
protected boolean doDecode(IoSession session, IoBuffer ioBuffer,
ProtocolDecoderOutput out) throws Exception {
ioBuffer.order(ByteOrder.LITTLE_ENDIAN);
log.debug("Server端#doDecode#剩余客户端消息大小:"+ioBuffer.remaining());
sysPrintLn("Server端#doDecode#ioBuffer读到剩余客户端消息大小:"+ioBuffer.remaining());
MessageInfo hmi=null;
String attrStr=ATTRIBUTE_NAME+session.getId();
Object o=session.getAttribute(attrStr);
if(null!=o && (o instanceof MessageInfo)){
hmi=(MessageInfo)o;
}
//修改缓冲区的字节顺序为little-endian,按照此顺序,多字节值的字节顺序是从最低有效位到最高有效位的。
    if(null==hmi){
    sysPrintLn("null==hmi");
    if(ioBuffer.remaining()>4){
    sysPrintLn("ioBuffer.remaining()>4");
    hmi=new MessageInfo();
    short  bodyLength= ioBuffer.getShort();
    short  msgIdentify=ioBuffer.getShort();
    hmi.setMsgBodySize(bodyLength);
    hmi.setMsgIdentify(msgIdentify);
    sysPrintLn("ioBuffer.position [null==hmi]:"+ioBuffer.position());
    sysPrintLn("bodyLength:"+bodyLength);
    sysPrintLn("msgIdentify:"+msgIdentify);
    session.setAttribute(attrStr,hmi);
    sysPrintLn(" [null==hmi]将再次调用当前解码方法!");
    return true;
    }else{
    sysPrintLn("ioBuffer.remaining()<=4");
    sysPrintLn("将继续接收!");
    return false;
    }
    }else{
    sysPrintLn(" [null!=hmi]");
    sysPrintLn("剩余byte大小1:"+ioBuffer.remaining());
if (ioBuffer.remaining() >= hmi.getMsgBodySize()) {
sysPrintLn("ioBuffer.remaining() >= hmi.getMsgbodySize()!");
/*
* 检查缓冲区的可用字节数是否大于等于消息体长度,即是否读取到消息体了。
*/
byte[] messageBody = new byte[hmi.getMsgBodySize()]; // 创建定长的数组存放消息体
ioBuffer.get(messageBody); // 从缓冲区中读取bodyLength字节的数据填充进数组
String msgbody = new String(messageBody,charset); // 设置请求的消息体
sysPrintLn("msgbody:"+msgbody);
hmi.setMsgBody(msgbody);
/*
* 将session对象的“HelperMsgInfo”键及其对应的属性值移除从而:
* 1、将bodySize键设置成无值状态,代表消息体已经解析完成。再次进入等待解析消息头阶段
* 2、释放存储“HelperMsgInfo”键的属性值占用的内存。
*/
session.removeAttribute(attrStr);
/*
* 将解码后生成的请求对象对象抛给位于应用层的Handler处理,或者抛给下一层解码器(如果存在)。
*/
out.write(hmi);
/*
* 因为当一条完整消息解析完成后,这时缓冲区内可能还有足够的积累数据可以继续解析下一条消息(也可能没有),
* 返回true使框架再次调用doDecode方法 。 
* 即使缓冲区内没有足够的数据了,也应该留给下次调用doDecode方法时去判断。
*/
sysPrintLn("[null!=hmi]将再次调用当前解码方法!");
return true;
} else {
sysPrintLn("ioBuffer.position *****:"+ioBuffer.position());
sysPrintLn("剩余byte大小 ****:"+ioBuffer.remaining());
sysPrintLn("ioBuffer.remaining() < hmi.getMsgbodySize()!");
/*
* 如果缓冲区内可用字节个数不足以构成完整的消息体,
* 直接返回false告诉框架不要再回调doDecode方法,
* 直到网络获取到数据压进缓冲区时再调用
*/
sysPrintLn("将继续接收!");
return false;
}
    }
}

private void sysPrintLn(String s){
if(SocketServerDecoder.ifPrintDebugInfo){
System.out.println(s);
}
}
}

Mina传输大数组,多路解码,粘包问题的处理

最近刚刚在做JAVA通信方面,初次接触mina,边根据网上查找的资料,结合自身的实际问题,作出了如下整理,希望能给类似问题的朋友帮助。 我的实际情况:    1,传递的业务数据种类很多,这就决定了...
  • sangsa
  • sangsa
  • 2015-11-23 16:36:00
  • 2343

MINA框架中的编码解码以及对粘包断包的处理

我们都知道MINA中是使用责任链的方式来实现将二进制字节流数据转换为java对象,或者将java对象转换为二进制字节流数据的,那么这个转换过程到底是怎么进行的呢?这就涉及到MINA中的编码与解码问题了...
  • hzw19920329
  • hzw19920329
  • 2016-08-14 19:02:06
  • 3664

mina框架详解

Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),M...
  • w13770269691
  • w13770269691
  • 2013-02-26 17:13:31
  • 68630

mina自定义编解码器接收处理byte数组(同时解决数据传输中的粘包、缺包问题)

我们在自定义传输协议时,通常都是采用字节数组的方式进行传送,如何正确接收和解码byte数组? 假设我们自定义了传输协议: 字节数组的前4个字节是要传输的数据长度,后面跟数据。我们用mina可以这...
  • jbgtwang
  • jbgtwang
  • 2014-05-19 17:07:36
  • 13833

MINA源码分析---CumulativeProtocolDecoder协议解码器

一般用户写解码器直接继承 CumulativeProtocolDecoder 类就行啦,实现里面的doDecode方法 更详细的解释在源码中 在 /* */ package org.a...
  • cao478208248
  • cao478208248
  • 2014-12-06 20:41:14
  • 3563

CumulativeProtocolDecoder的deCode()

mina的粘包拆包其实是蛮简单的,只是一开始没搞清楚原理。 我们要约定数据包的格式,我这里的是(4个字节长度+json的string字符串) 1:写一个 ProtocolCodecF...
  • qazwsx185313301
  • qazwsx185313301
  • 2014-12-27 22:49:06
  • 1977

Mina框架断包、粘包问题解决方案

Mina框架断包、粘包问题解决方案 Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对...
  • rchm8519
  • rchm8519
  • 2014-08-07 14:38:35
  • 23355

Mina 粘包、拆包的实现-网上常见的代码有bug。。

mina的粘包拆包其实是蛮简单的,只是一开始没搞清楚原理。 我们要约定数据包的格式,我这里的是(4个字节长度+json的string字符串) 1:写一个 ProtocolCodecFacto...
  • loseleo
  • loseleo
  • 2013-06-21 00:08:53
  • 14997

Java字节数组处理工具类-Mina的IoBuffer封装

Java字节数组处理工具类-Mina的IoBuffer封装处理网络数据的项目中经常需要处理字节数据,Java的ByteBuffer很强大,但是Mina和Netty两个常用的网络通信框架都拥有自己的数据...
  • handsome_926
  • handsome_926
  • 2016-05-30 23:59:13
  • 3173

Mina框架数据接收

数据接收流程: 接收流程NIOSession再下层就不看了,看看read完数据的流程,主要filter。 读取到数据,就开始传到FilterChain里面了。 fireMessageReceive...
  • wzm112358
  • wzm112358
  • 2015-06-08 11:13:00
  • 1671
收藏助手
不良信息举报
您举报文章:MINA通信deCode实现
举报原因:
原因补充:

(最多只允许输入30个字)