Netty是一个高性能的NIO框架,它支持TCP粘包分包,在Netty4中对ByteBuf进行池化(即对内存加以管理,内存池化加以复用),采用堆外内存,可以减少不必要的对象创建,对GC更友好。
Netty的核心组件
ByteBuf:保存socket读写数据,如果是堆外内存,直接与TCP发送和接收缓冲区交互
Channel:可以注册到EventLoop上
ChannelHandler:可以定义编码解码,socket数据读写,检测socket连接等操作
ChannelPopeline:ChannelHandler的容器
EventLoop:管理Channel
Bootstrap:启动组件
Netty的解码
基于分割符协议的
DelimiterBasedFrameDecoder:使用任何由用户提供的分隔符来提取帧的通用解码器
LineBasedFrameDecoder:提取由行尾符(\n或者\r\n)分隔的帧的解码器。这个解码器比DelimiterBasedFrameDecoder更快
基于长度协议的
FixedLengthFrameDecoder:提取在调用构造函数时指定的定长帧,在实际运用中可能需要对传输数据进行添加空格的操作
LengthFieldBasedFrameDecoder:根据编码进帧头部中的长度值提取帧;该字段的偏移量以及长度在构造函数中指定
简单的NettyServer
public void server(int port) throws Exception {
// 为非阻塞模式使用NioEventLoopGroup,定义处理event的线程数为5
EventLoopGroup group = new NioEventLoopGroup(5);
try {
ServerBootstrap b = new ServerBootstrap(); // 创建ServerBootstrap
b.group(group).channel(NioServerSocketChannel.class) //基于NIO的形式
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer() {
//每个channel连接时,都会调用此方法对ChannelHandler进行初始化
@Override
protected void initChannel(Channel channel) throws Exception {
{
//定义channel 60秒无数据读取断开连接
channel.pipeline().addLast(new ReadTimeoutHandler(60));
//采用定长解码器进行解码
channel.pipeline().addLast(new FixedLengthFrameDecoder(50));
//自定义channelHandler
channel.pipeline().addLast(new ServerHandler());
}
} // 指定Channel-Initializer,对于每个已接受的连接都调用它
});
ChannelFuture f = b.bind().sync(); // 绑定服务器以接受连接
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync(); // 释放所有的资源
}
}