Netty学习纪要之编码与解码

刚刚工作的时候(虽然现在也是刚刚工作)接触过Netty,不过那时候小白(现在依然是),不知道Netty是个什么东西,甚至都不知道NIO,只知道工程的框架里用了Netty。后来超哥(我眼里的大神)告诉我学学NIO,然后了解一下Netty框架,所以小白谨遵教诲,如今抽出时间仔细的从基础学起,直到用Netty发送字节信息的时候都还算顺利,但是昨天准备发送自定义消息的时候出了问题,通道可以建立起来,但是发送却总是不成功,后来百度、谷歌、stackoverflow了一下,原来是编码与解码的问题。Netty是NIO框架,所以能传字节是必须的,但是传输对象的时候就有了问题,缓冲区里传的还是字节数组,而我们要传一个对象,所以这就需要我们把对象转化为字节数组写入缓冲区传输,接收的时候将字节数组读出并转化为对象,只有这样,自定义的消息才能在客户端与服务器之间传输,当然,传输的消息要实现Serializable接口。

以下上干货,工具类

package org.aurora.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import io.netty.buffer.ByteBuf;

public class Util {
	public static byte[] readBuffer(ByteBuf buffer){
		byte[] bs = new byte[buffer.readableBytes()];
		buffer.readBytes(bs);
		return bs;
	}
	
	public static byte[] object2Bytes(Object obj){
		byte[] bs = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(bos);
			oos.writeObject(obj);
			bs = bos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			try {
				oos.close();
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return bs;
	}
	
	public static Object bytes2Object(byte[] bs){
		Object obj = null;
		ByteArrayInputStream bis = new ByteArrayInputStream(bs);
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(bis);
			obj = ois.readObject();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally{
			try {
				ois.close();
				bis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return obj;
	}
}
自定义消息

package org.aurora.model;

import java.io.Serializable;

public class Commond implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String content;

	public Commond(String content){
		this.content = content;
	}
	
	public String getContent(){
		return content;
	}
}
编码
package org.aurora.util;

import org.aurora.model.Commond;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

public class CommondEncoder extends MessageToByteEncoder{

	@Override
	protected void encode(ChannelHandlerContext ctx, Commond msg, ByteBuf out)
			throws Exception {
		// 将对象转化为字节数组
		byte[] bs = Util.object2Bytes(msg);
		// 将字节数组写入缓冲区
		out.writeBytes(bs);
		ctx.flush();
	}

}
解码
package org.aurora.util;

import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

public class CommondDecoder extends ByteToMessageDecoder{

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in,
			List out) throws Exception {
		// 读取ByteBuf中的流数据,读出字节数组
		byte[] bs = Util.readBuffer(in);
		// 将字节数组转化为对象
		Object obj = Util.bytes2Object(bs);
		// 将对象放入list
		out.add(obj);
	}

}
 
  
最后只要在设置Handler的时候设置这两个编码、解码器就可以了。

你可能感兴趣的:(Netty学习纪要之编码与解码)