mina粘包、多包和少包的解决方法

18 篇文章 0 订阅
14 篇文章 0 订阅

转 :http://hi.baidu.com/leosonshine/item/966cf45af5abd88209be17cc

使用过mina的同学应该都遇到到过,在解码时少包、多包的问题,查阅了很多资料还是迷迷糊糊的,经过

不懈努力,终于解决了。原来解决方法是那样的简单。废话少说,请看列子。

问题:我发送的是xml字符串数据,在发送数据后,接收方在解码的时候可能接到1条,也可能是多条,还

可能是半条或一条半,解决方法就是使用CumulativeProtocolDecoder

首先,在编码的时候要把前4位设成标志位,标志消息内容的长度。里面的重点是doDecode的返回值,一

定要继承CumulativeProtocolDecoder 哦。

清看decode的写法:

Java代码 

public class  AsResponseDecoder extends CumulativeProtocolDecoder {  

private static Logger LOG = LoggerFactory.getLogger(AsResponseDecoder.class);  

private final Charset charset;  


public AsResponseDecoder(Charset charset){  

this.charset = charset;  

}  




public boolean doDecode(IoSession session, IoBuffer in,  

ProtocolDecoderOutput out) throwsException {  


CharsetDecoder cd = charset.newDecoder();  

if(in.remaining() > 0){//有数据时,读取4字节判断消息长度

byte[] sizeBytes = new byte[4];  

in.mark();//标记当前位置,以便reset

in.get(sizeBytes);//读取前4字节

//NumberUtil是自己写的一个int转byte[]的一个工具类

intsize = NumberUtil.byteArrayToInt(sizeBytes);  

//如果消息内容的长度不够则直接返回true

if(size > in.remaining()){//如果消息内容不够,则重置,相当于不读取size

in.reset();  

return false;//接收新数据,以拼凑成完整数据

} else{  

byte[] bytes = new byte[size]; 

in.get(bytes, 0, size);  

String xmlStr = newString(bytes,"UTF-8");  

System.out.println("------------"+xmlStr);  

if(null!= xmlStr && xmlStr.length() > 0){  

AsResponse resCmd = newAsResponse();  

AsXmlPacker.parse(resCmd, xmlStr);  

if(resCmd != null){  

out.write(resCmd);  

}  

}  

if(in.remaining() > 0){//如果读取内容后还粘了包,就让父类再给俺


一次,进行下一次解析  

return true;  

}  

}  

}  

return false;//处理成功,让父类进行接收下个包

}  




下面附上Encode类

Java代码 

public class  AsResponseEncoder extends  ProtocolEncoderAdapter {  

private final Charset charset;  


public AsResponseEncoder(Charset charset){  

this.charset = charset;  

}  


public void encode(IoSession session, Object message,  

ProtocolEncoderOutput out) throwsException {  

CharsetEncoder ce = charset.newEncoder();  

IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true);  


AsResponse respCmd = (AsResponse) message;  


String xml = AsXmlPacker.pack(respCmd);//将对象转成xml

byte[] bytes = xml.getBytes();  

byte[] sizeBytes = NumberUtil.intToByteArray(bytes.length);  


buffer.put(sizeBytes);//将前4位设置成数据体的字节长度

buffer.put(bytes);//消息内容

buffer.flip();  

out.write(buffer);  

}  





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值