所有文章
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數據的時候異常觸發
