netty4 自定义消息协议

消息协议设计为:

  head(4字节 body的长度)  + body

 

1.解码部分

  1.1解码body长度

       

public class MyLengthDecoder extends ByteToMessageDecoder {

    // TODO maxFrameLength + safe skip + fail-fast option

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        in.markReaderIndex();
        final byte[] buf = new byte[4];
        
        for (int i = 0; i < buf.length; i ++) {
            if (!in.isReadable()) {
                in.resetReaderIndex();
                return;
            }

            buf[i] = in.readByte();
           /* if (buf[i] >= 0) {
                int length = CodedInputStream.newInstance(buf, 0, i + 1).readRawVarint32();
                if (length < 0) {
                    throw new CorruptedFrameException("negative length: " + length);
                }

                if (in.readableBytes() < length) {
                    in.resetReaderIndex();
                    return;
                } else {
                    out.add(in.readBytes(length));
                    return;
                }
            }*/
        }
        //将4个字节头转化 成消息体大小
        int length = ByteUtil.toInt(buf);
        if (length < 0) {
            throw new CorruptedFrameException("negative length: " + length);
        }

        if (in.readableBytes() < length) {
            in.resetReaderIndex();
            return;
        } else {
            out.add(in.readBytes(length));
            return;
        }
    //    throw new CorruptedFrameException("length wider than 32-bit");
    }
}

1.2 解码body

  

@Sharable
public class MyDecoder extends MessageToMessageDecoder<ByteBuf> {
 
 
    /**
     * Creates a new instance.
     */
    public MyDecoder() {
    }

    public MyDecoder(MessageLite prototype, ExtensionRegistry extensionRegistry) {
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
        final byte[] array;
        final int offset;
        final int length = msg.readableBytes();
        if (msg.hasArray()) {
            array = msg.array();
            offset = msg.arrayOffset() + msg.readerIndex();
        } else {
            array = new byte[length];
            msg.getBytes(msg.readerIndex(), array, 0, length);
            offset = 0;
        }
        
        MessageObj messageObj = new MessageObj();
        messageObj.setValue(array);
        out.add(messageObj); 
    }
}

  

2.编码部分

 2.1.编码head长度

@Sharable
public class MyLengthEncoder extends MessageToByteEncoder<ByteBuf> {

    @Override
    protected void encode(
            ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
        int bodyLen = msg.readableBytes();
        int headerLen =4; 
        //在这个缓冲区写入的字节,此方法返回无副作用。
        out.ensureWritable(headerLen + bodyLen);

    /*    CodedOutputStream headerOut =
                CodedOutputStream.newInstance(new ByteBufOutputStream(out));
        headerOut.writeRawVarint32(bodyLen);
        headerOut.flush();*/ 
        
        byte [] b = ByteUtil.toByteArray(bodyLen, 4);
        out.writeBytes(wrappedBuffer(b)); 
        
        out.writeBytes(msg, msg.readerIndex(), bodyLen);
    }
}

  

 2.2.编码body

@Sharable
public class MyEncoder extends MessageToMessageEncoder<MessageObj> {
    @Override
    protected void encode(
            ChannelHandlerContext ctx, MessageObj msg, List<Object> out) throws Exception {
        if (msg instanceof MessageObj) {
            out.add(wrappedBuffer( msg.getValue()));
            return;
        }
       
    }
}

  

 3.消息实体类和字节转换工具

 ByteUtil 

   

public class ByteUtil {
	//int 转化字节数组
	public static byte[] toByteArray(int iSource, int iArrayLen) {
	    byte[] bLocalArr = new byte[iArrayLen];
	    for (int i = 0; (i < 4) && (i < iArrayLen); i++) {
	        bLocalArr[i] = (byte) (iSource >> 8 * i & 0xFF);
	    }
	    return bLocalArr;
	}
	//将byte数组bRefArr转为一个整数,字节数组的低位是整型的低字节位
	public static int toInt(byte[] bRefArr) {
	   int iOutcome = 0;
	   byte bLoop;
	   for (int i = 0,len = bRefArr.length; i < len; i++) {
	       bLoop = bRefArr[i];
	       iOutcome += (bLoop & 0xFF) << (8 * i);
	   }
	   return iOutcome;
	}  
	public static void main(String[] args) {
		byte[] bb = toByteArray(1000, 4);
		int len = toInt(bb);
		System.out.println(len);
	}
}

MessageObj

public class MessageObj {
	private byte[] value;

	public byte[] getValue() {
		return value;
	}

	public void setValue(byte[] value) {
		this.value = value;
	}
	
}

  

  

 

  

 

 

   

posted on 2014-06-27 18:41  hopesprings  阅读(481)  评论(0)    收藏  举报

导航