MINA通信deCode实现

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);
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值