MINA2中的拆包组包的处理及一些方法

1.position 

例: 
Java代码  收藏代码
  1. position()   

第一次使用返回值为当前位置:0 


position(8) 返回第8个字节以后的数据(包括第8个)可以和 limit 联合使用 
如: 
Java代码  收藏代码
  1. buffer.position(3);   
  2. buffer.limit(7);   
  3. ByteBuffer slice = buffer.slice();   



再次调用 position() 返回:8 


2.remaining 

例: 

Java代码  收藏代码
  1. ByteBuffer byt = ByteBuffer.allocate(128,false);   

第一次调用 
byt.remaining(); 返回 128 

A、使用:byt.putInt(5);或者byt.getInt()或者byt.get(字节数组)等方法 

之后调用 byt.remaining(); 返回 124 

B、但使用 byt.putInt(5,4);或者byt.getInt(0) 之后,调用方法 
byt.remaining();返回 128 


3.prefixedDataAvailable 

prefixedDataAvailable(4) int 

该方法很好用。判断前四字节的整型值是否大于等于整个缓冲区的数据。可以方便的判断一次 
messageReceived 过来的数据是否完整。(前提是自己设计的网络通讯协议前四字节等于发送数据的长度) 

prefixedDataAvailable(2) Short int 


网上找到的例子: 

Java代码  收藏代码
  1. protected boolean doDecode(IoSession session, IoBuffer in,   
  2.            ProtocolDecoderOutput out) throws Exception {   
  3.        if (in.prefixedDataAvailable(4, Constants.MAX_COMMAND_LENGTH)) {   
  4.            int length = in.getInt();   
  5.            byte[] bytes = new byte[length];   
  6.            in.get(bytes);   
  7.            int commandNameLength = Constants.COMMAND_NAME_LENGTH;   
  8.            byte[] cmdNameBytes = new byte[commandNameLength];   
  9.            System.arraycopy(bytes, 0, cmdNameBytes, 0, commandNameLength);   
  10.            String cmdName = (new String(cmdNameBytes)).trim();   
  11.            AbstractTetrisCommand command = TetrisCommandFactory   
  12.                .newCommand(cmdName);   
  13.            if (command != null) {   
  14.                byte[] cmdBodyBytes = new byte[length - commandNameLength];   
  15.                System.arraycopy(bytes, commandNameLength, cmdBodyBytes, 0,   
  16.                    length - commandNameLength);   
  17.                command.bodyFromBytes(cmdBodyBytes);   
  18.                out.write(command);   
  19.            }   
  20.            return true;   
  21.        } else {   
  22.            return false;   
  23.        }   
  24.    }   


MINA中分段读取数据的方法: 


2. ProtobufRPCRequestProtocolDecoder.java 

Java代码  收藏代码
  1. package com.lizongbo.protobufrpc;  
  2.   
  3. import org.apache.mina.filter.codec.ProtocolDecoder;  
  4. import org.apache.mina.core.session.IoSession;  
  5. import org.apache.mina.core.buffer.IoBuffer;  
  6. import org.apache.mina.filter.codec.ProtocolDecoderOutput;  
  7. import org.apache.mina.core.session.AttributeKey;  
  8.   
  9. public class ProtobufRPCRequestProtocolDecoder implements ProtocolDecoder {  
  10.   
  11. private static final AttributeKey BUF_BYTE = new AttributeKey(  
  12. ProtobufRPCRequestProtocolDecoder.class"bufb");  
  13.   
  14. public void decode(IoSession ioSession, IoBuffer ioBuffer,  
  15. ProtocolDecoderOutput protocolDecoderOutput) throws  
  16. Exception {  
  17. try {  
  18. IoBuffer bufTmp = null;  
  19. byte[] buf = (byte[]) ioSession.getAttribute(BUF_BYTE);  
  20. if (buf == null) {  
  21. System.out.println("没有尚未处理的数据" + ioBuffer.remaining());  
  22. bufTmp = ioBuffer;  
  23. else {  
  24. System.out.println("合并尚未处理的数据" + ioBuffer.remaining());  
  25. bufTmp = IoBuffer.allocate(buf.length + ioBuffer.remaining());  
  26. bufTmp.setAutoExpand(true);  
  27. bufTmp.put(buf);  
  28. bufTmp.put(ioBuffer);  
  29. bufTmp.flip();  
  30. while (bufTmp.remaining() >= 4  
  31. && bufTmp.remaining() >= bufTmp.getInt(bufTmp.position())) { // 循环处理数据包  
  32. System.out.println("循环处理数据包");  
  33. int dataLen = bufTmp.getInt(bufTmp.position());  
  34. byte[] b = new byte[dataLen];  
  35. bufTmp.get(b);  
  36. ProtobufRPCRequest pak = new ProtobufRPCRequest();  
  37. pak.setReqByteLen(b.length);  
  38. pak.readFrom(b, 4);  
  39. System.out.println("往下传递");  
  40. protocolDecoderOutput.write(pak);  
  41. }  
  42. if (bufTmp.hasRemaining()) { // 如果有剩余的数据,则放入Session中  
  43. System.out.println("如果有剩余的数据,则放入Session中" + bufTmp.remaining());  
  44. byte[] tmpb = new byte[bufTmp.remaining()];  
  45. bufTmp.get(tmpb);  
  46. ioSession.setAttribute(BUF_BYTE, tmpb);  
  47. }  
  48. catch (Exception ex) {  
  49. ex.printStackTrace();  
  50. }  
  51. }  
  52.   
  53. public void dispose(IoSession session) throws Exception {  
  54. System.out.println("dispose");  
  55.   
  56. }  
  57.   
  58. public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws  
  59. Exception {  
  60. System.out.println("finishDecode");  
  61. }  
  62.   
  63. }  
原文地址:https://www.cnblogs.com/balaamwe/p/2319194.html