Netty笔记5:Netty开发实例
Netty笔记1:线程模型
Netty笔记2:零拷贝
Netty笔记3:NIO编程
Netty笔记4:Epoll
Netty笔记5:Netty开发实例
Netty笔记6:Netty组件
Netty笔记7:ChannelPromise通知处理
Netty笔记8:ByteBuf使用介绍
Netty笔记9:粘包半包
Netty笔记10:LengthFieldBasedFrameDecoder
Netty笔记11:编解码器
Netty笔记12:模拟Web服务器
Netty笔记13:序列化
文章目录
- 示例
- 总结
示例
服务端处理器
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buffer = (ByteBuf)msg;
System.out.println("接收到数据:" + buffer.toString(CharsetUtil.UTF_8));
super.channelRead(ctx, msg);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer(("服务器已接受。"+System.getProperty("line.separator")).getBytes(CharsetUtil.UTF_8)));
}
}
服务端
public class NettyServer {
/*
创建这个服务端,和NIO编程有很多相像之处,
*/
public static void main(String[] args) throws InterruptedException {
// 线程组
NioEventLoopGroup group = new NioEventLoopGroup();
// 启动器
ServerBootstrap bootstrap = new ServerBootstrap();
// 添加线程组
try {
bootstrap.group(group)
// server指定为ServerChannel
.channel(NioServerSocketChannel.class)
// 绑定端口
.localAddress(8080)
// 事件处理器
// 通过channel初始化器添加handle
// ServerSocketChannel要产生socketChannel,便要对socketChannel进行初始化
// 因为childHandler是对应socket,这里是server,会有很多客户端的socket
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// handle是在piple中执行的,所以这里要添加到piple
socketChannel.pipeline().addLast(new ServerHandler());
}
});
// 绑定到服务器(这里是异步的)
ChannelFuture future = bootstrap.bind()
// 这里阻塞直到绑定完成
.sync();
// 同样,阻塞直到channel关闭
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
group.shutdownGracefully().sync();
}
}
}
客户端处理器
public class ChildHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
System.out.println("客户端收到:" + byteBuf.toString(CharsetUtil.UTF_8));
channelHandlerContext.channel();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// 连接成功后激活这个方法
ctx.writeAndFlush(Unpooled.copiedBuffer("你好".getBytes(CharsetUtil.UTF_8)));
}
}
客户端
public class NettyClient {
public static void main(String[] args) throws InterruptedException {
// 线程组
NioEventLoopGroup group = new NioEventLoopGroup();
// 启动器
Bootstrap bootstrap = new Bootstrap();
try {
// 设置线程组
bootstrap.group(group)
// 治党channel
.channel(NioSocketChannel.class)
// 指定服务端地址
.remoteAddress(new InetSocketAddress("127.0.0.1", 8080))
// 客户端都是socketChannel
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// 只要是netty,那么都需要添加到piple
// 处理器都是在piple中执行
socketChannel.pipeline().addLast(new ChildHandler());
}
});
// 阻塞直到连接完成;
// sync()是阻塞
ChannelFuture future = bootstrap.connect().sync();
//
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
group.shutdownGracefully().sync();
}
}
}
总结
Netty
的编程可以说是比较简单的,他是一个框架,只需要固定的模式去编写就行,如上面示例中NioEventLopGrop
和Bootstrap
,每个Netty
编程都需要写,是一个固定句式,还有后面的channel、address、handler
都是固定句式,所以,我们只要按照规定句式编写,就可以完成一个简单的Netty
应用程序,而业务逻辑处理,通过Handler
添加就行。