所有文章
https://www.cnblogs.com/lay2017/p/12922074.html
正文
要构建netty的tcp服务端,你需要
1.创建EventLoopGroup
2.配置一个ServerBootStrap
3.创建ChannelInitializer
4.启动服务
代码如下
EventLoopGroup group = new NioEventLoopGroup(); try{ ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(group); serverBootstrap.channel(NioServerSocketChannel.class); serverBootstrap.localAddress(new InetSocketAddress("localhost", 9999)); serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() { protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new HelloServerHandler()); } }); ChannelFuture channelFuture = serverBootstrap.bind().sync(); channelFuture.channel().closeFuture().sync(); } catch(Exception e){ e.printStackTrace(); } finally { group.shutdownGracefully().sync(); }
创建EventLoopGroup
第一步是创建EventLoopGroup,相对比较简单,如
EventLoopGroup group = new NioEventLoopGroup();
创建ServerBootstrap
第二步是创建ServerBootstrap
ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(group); serverBootstrap.channel(NioServerSocketChannel.class); serverBootstrap.localAddress(new InetSocketAddress("localhost", 9999));
group方法把EventLoopGroup绑定到了ServerBootstrap上
EventLoopGroup是NioEventLoopGroup实现,所以这里要指明channel是NioServerSocketChannel
最后通过InetSocketAddress指明domain + port
创建ChannelInitializer
第三步是创建ChannelInitializer
serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() { protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new HelloServerHandler()); } });
ChannelInitializer绑定到了serverBootstrap上
pipeline添加ChannelHandler
启动
最后一步,启动服务
ChannelFuture channelFuture = serverBootstrap.bind().sync();
bind方法返回ChannelFuture,可以知道绑定到domain + port什么时候完成。sync方法会等待服务启动完成
HelloChannelHandler
最后给出HelloChannelHandler代码
public class HelloServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf inBuffer = (ByteBuf) msg; String received = inBuffer.toString(CharsetUtil.UTF_8); System.out.println("Server received: " + received); ctx.write(Unpooled.copiedBuffer("Hello " + received, CharsetUtil.UTF_8)); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(Unpooled.EMPTY_BUFFER) .addListener(ChannelFutureListener.CLOSE); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
channelRead方法是从SocketChannel中read数据的时候触发,channelReadComplete方法是没有可读数据的时候触发,exceptionCaught方法是从socket中read数据或者write数据的时候异常触发