Netty 5.x 2.自定义编解码器

一个简单的Netty服务  接收什么信息就回复什么信息

总目录

Netty 5.x 1.netty服务器搭建

Netty 5.x 2.自定义编解码器

当前目录

Maven依赖

创建服务并绑定端口  以及 编解码器

解码器

编码器

接收发送数据类

消息格式类(实体类/协议格式)


 

Maven依赖

    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>5.0.0.Alpha2</version>
    </dependency>

创建服务并绑定端口  以及 编解码器

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class Server extends Thread{
	private int port = -1;
	
	public Server(int port) {
		this.port = port;
	}
	
	@Override
	public void run() {
		bind(port);
	}
	
	private void bind(int port) {
		EventLoopGroup boss = new NioEventLoopGroup(1);
		EventLoopGroup work = new NioEventLoopGroup();
 
		ServerBootstrap bootstrap =  new ServerBootstrap();
		try {
			bootstrap.group(boss, work)
			.channel(NioServerSocketChannel.class)//注册factory
			.childHandler(new ChannelInitializer<Channel>() {//注册piepline
				@Override
				protected void initChannel(Channel sc) throws Exception {//初始化连接
					sc.pipeline() 
					.addLast(new Decode())				//添加自定义解码器
					.addLast(new Encode())				//添加自定义编码器
					.addLast(new ServerHandle());		//添加处理网络io类		
				}
			})
			.option(ChannelOption.SO_BACKLOG, 128)
			.childOption(ChannelOption.TCP_NODELAY, true)//TCP无掩饰
			.childOption(ChannelOption.SO_KEEPALIVE,true);//清除死连接,维持活跃的
			ChannelFuture future = bootstrap.bind(port);
			future.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
            boss.shutdownGracefully();
            work.shutdownGracefully();
        }
	}
 
 
}

解码器

import java.util.List;

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

public class Decode extends ByteToMessageDecoder {
	private static final int MIN_LENGTH = 2+2+2;	//数据内容为空时最小长度 即(协议头、版本号、消息长度(长度=0时消息最短))
	private static final int MAX_LENGTH = 2048;		//约定数据最大长度(防止socket字节流攻击)
	
	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
		try {
			if(in.readableBytes()<MIN_LENGTH) {//可读取字节数少于最小长度
				return;
			}
			if(in.readableBytes() > MAX_LENGTH){//可读字节数大于约定最大长度
				in.skipBytes(in.readableBytes());
				return;
			}
			while(true) {
				in.markReaderIndex();
				if(in.readShort() == Message.TAG){//寻找协议头
					if(in.readShort()==Message.VERSION) {
						break;
					}
				}
				in.resetReaderIndex();
				in.readByte();
				if(in.readableBytes() <= MIN_LENGTH){
					return;
				}
				if(in.readableBytes() > MAX_LENGTH){
					in.skipBytes(in.readableBytes());
					return;
				}
			}
			Message message = new Message();
			int length = in.readInt();
			message.setLENGTH(length);
			byte[] data = new byte[length-8];
			in.readBytes(data);
			message.setDATA(new String(data,"ISO-8859-1"));
			out.add(message);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}

}

编码器

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

public class Encode extends MessageToByteEncoder<Message> {
	

	@Override
	protected void encode(ChannelHandlerContext ctx, Message message, ByteBuf out) throws Exception {
		out.writeShort(Message.TAG);
		out.writeShort(Message.VERSION);
		out.writeBytes(message.getDATA().getBytes("ISO-8859-1"));
		out.setShort(4, out.readableBytes()+2);
	}

}

接收发送数据类

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class ServerHandle extends SimpleChannelInboundHandler<Message>{
	 
	@Override
	protected void messageReceived(ChannelHandlerContext cx, Message message) throws Exception {
		
		System.out.println(message);
		
		cx.write(message);
		cx.flush();
	}
 
}

消息格式类(实体类/协议格式)

public class Message {

	public final static short TAG = (short) 0xFEFD;		//协议头(长度2字节)
	public final static short VERSION = 0x0100;	//版本号(长度2字节)
	private int LENGTH;					//消息长度(整个数据包长度,2字节)
	private String DATA;				//消息内容
	public int getLENGTH() {
		return LENGTH;
	}
	public void setLENGTH(int lENGTH) {
		LENGTH = lENGTH;
	}
	public String getDATA() {
		return DATA;
	}
	public void setDATA(String dATA) {
		DATA = dATA;
	}
	@Override
	public String toString() {
		return "Message [TAG=" + TAG + ", VERSION=" + VERSION + ", LENGTH=" + LENGTH + ", DATA=" + DATA + "]";
	}
	
	
}

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dan淡淡的心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值