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) 收藏 举报
浙公网安备 33010602011771号