Netty(十) Netty5.x 自定义编码解码器
netty学习目录
一、Netty(一) NIO例子
二、Netty(二) netty服务端
三、Netty(三) Netty客户端+服务端
四、Netty(四) 简化版Netty源码
五、Netty(五)Netty5.x服务端
六、Netty(六) Netty Http 服务器例子
七、Netty(七) Netty服务端+客户端代码
八、Netty(八) Netty多客户端连接例子
九、Netty(九) Netty会话清除
十、Netty(十) Netty自定义编码器解码器
十一、Netty(十一) Netty对象传输
基于Netty5.x自定义编解码器
自定义消息实体
package com.zqw.netty5x.customproto;
import java.io.Serializable;
public class Header implements Serializable {
private int tag;
private int commandCode;
private int version;
private int length;
public int getTag() {
return tag;
}
public void setTag(int tag) {
this.tag = tag;
}
public int getCommandCode() {
return commandCode;
}
public void setCommandCode(int commandCode) {
this.commandCode = commandCode;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
@Override
public String toString() {
return "Header{" +
"tag=" + tag +
", commandCode=" + commandCode +
", version=" + version +
", length=" + length +
'}';
}
}
package com.zqw.netty5x.customproto;
import java.io.Serializable;
public class Message implements Serializable {
private Header header;
private Object data;
public Header getHeader() {
return header;
}
public void setHeader(Header header) {
this.header = header;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "Message{" +
"header=" + header +
", data=" + data +
'}';
}
}
解码器
package com.zqw.netty5x.customproto;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.List;
public class MyDecoder extends ByteToMessageDecoder {
private int MIN_LENGTH = 4 + 4 + 4 + 4;
private int TAG = 1;
private int MAX = 2048;
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if(in.readableBytes() <= MIN_LENGTH){
return;
}
if(in.readableBytes() > MAX){
in.skipBytes(in.readableBytes());
}
Message message = new Message();
int tag = 0;
while(true){
in.markReaderIndex();
if((tag = in.readInt()) == TAG){
break;
}
in.resetReaderIndex();
in.readByte();
if(in.readableBytes() <= MIN_LENGTH){
return;
}
}
int commandCode = in.readInt();
int version = in.readInt();
int length = in.readInt();
Header header = new Header();
header.setCommandCode(commandCode);
header.setLength(length);
header.setTag(tag);
header.setVersion(version);
message.setHeader(header);
byte[] bytes = new byte[length];
if(length > 0){
if(in.readableBytes() < length){
//包还没齐,返回
in.resetReaderIndex();
return;
}
// System.out.println("bytebuffer可读的范围" + in.readableBytes());
// if(in.readableBytes() > length){
// in.resetReaderIndex();
// System.out.println("返回了");
// return;
// }
in.readBytes(bytes);
String data = new String(bytes);
message.setData(data);
}
out.add(message);
}
}
编码器
package com.zqw.netty5x.customproto;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
public class MyEncoder extends MessageToByteEncoder<Message> {
@Override
protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
if(msg == null || msg.getHeader() == null){
throw new Exception("the encode message is null");
}
Header header = msg.getHeader();
int tag = header.getTag();
int commandCode = header.getCommandCode();
int version = header.getVersion();
int length = header.getLength();
Object data = msg.getData();
out.writeInt(tag);
out.writeInt(commandCode);
out.writeInt(version);
out.writeInt(0);
if(data != null){
String str = (String) data;
byte[] bytes = str.getBytes();
length = bytes.length;
out.writeBytes(bytes);
}
//写入length;
out.setInt(12, length);
}
}