Netty(十) Netty5.x 自定义编码解码器

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 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 {
    @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);
    }
}