1. 程式人生 > >一、netty初學,簡單的echo伺服器,客戶端

一、netty初學,簡單的echo伺服器,客戶端

無論伺服器還是客戶端都是由下面兩步組成 1、ChannelHandler 用與處理各種事件的邏輯處理。決定了連線建立後和接收到資訊後該如何處理。 直接或簡接要實現ChannelInboundHandler 介面. 2、Bootstrap啟動伺服器或客戶端 伺服器用 ServerBootstrap 客戶端用 BootStrap。 pom
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.0.29.Final</version>
</dependency>

EchoServerChannelHandler
packagetest01; importio.netty.buffer.ByteBuf; importio.netty.buffer.Unpooled; importio.netty.channel.ChannelFutureListener; importio.netty.channel.ChannelHandlerContext; importio.netty.channel.ChannelInboundHandlerAdapter; importio.netty.util.CharsetUtil; /** * Created by wujiazhen on 2018/1/15. */ public class
EchoServerChannelHandlerextendsChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg)throwsException { ByteBuf in = (ByteBuf)msg; System.out.println("server receive:"+in.toString(CharsetUtil.UTF_8)); ctx.write(msg); } @Override public void channelReadComplete(ChannelHandlerContext ctx)
throwsException { ctx.writeAndFlush(Unpooled.EMPTY_BUFFER) .addListener(ChannelFutureListener.CLOSE); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)throwsException { cause.printStackTrace();//5 ctx.close(); } }
伺服器啟動
packagetest01; importio.netty.bootstrap.ServerBootstrap; importio.netty.channel.*; importio.netty.channel.nio.NioEventLoopGroup; importio.netty.channel.socket.SocketChannel; importio.netty.channel.socket.nio.NioServerSocketChannel; importjava.net.InetSocketAddress; importjava.util.concurrent.TimeUnit; /** * Created by wujiazhen on 2018/1/15. */ public classEchoServer { private int port; publicEchoServer(){}; publicEchoServer(intport){ this.port=port; } public static void main(String args[]){ newEchoServer(2000).start(); } public void start() { NioEventLoopGroup group =newNioEventLoopGroup(); try{ /* 1.建立 EventLoopGroup 2.建立 ServerBootstrap 3.指定使用 NIO 的傳輸 Channel 4.設定 socket 地址使用所選的埠 5.新增 EchoServerHandler 到 Channel 的 ChannelPipeline */ ServerBootstrap bootstrap = newServerBootstrap() .channel(NioServerSocketChannel.class) .group(group) .localAddress(newInetSocketAddress(this.getPort())) .childHandler(newChannelInitializer<SocketChannel>() { public void initChannel(SocketChannel socketChannel)throwsException { /* ChannelInitializer 。當一個新的連線被接受,一個新的子 Channel 將被建立, ChannelInitializer 會新增我們EchoServerHandler 的例項到 Channel 的 ChannelPipeline。 正如我們如前所述,如果有入站資訊,這個處理器將被通知。 */ socketChannel.pipeline().addLast(newEchoServerChannelHandler()); } }); // 6.繫結的伺服器;sync 等待伺服器關閉 ChannelFuture future = bootstrap.bind().sync(); System.out.println(EchoServer.class.getName() + " started and listen on "+ future.channel().localAddress()); //7.關閉 channel 和 塊,直到它被關閉 future.channel().closeFuture().sync(); }catch(InterruptedException e) { e.printStackTrace(); }finally{ try{ group.shutdownGracefully().sync(); }catch(InterruptedException e) { e.printStackTrace(); } } } public int getPort() { returnport; } public void setPort(intport) { this.port= port; } }
客戶端handler
packagetest01; importio.netty.buffer.ByteBuf; importio.netty.buffer.Unpooled; importio.netty.channel.ChannelHandlerContext; importio.netty.channel.SimpleChannelInboundHandler; importio.netty.util.CharsetUtil; /** * Created by wujiazhen on 2018/1/15. */ public classEchoClientChannelHandlerextendsSimpleChannelInboundHandler { protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg)throwsException { ByteBuf in = (ByteBuf)msg; System.out.println("client receive:"+in.toString(CharsetUtil.UTF_8)); } @Override public void channelActive(ChannelHandlerContext ctx)throwsException { System.out.println("connect success"); ctx.writeAndFlush(Unpooled.copiedBuffer("客戶端:建立.....",CharsetUtil.UTF_8)); super.channelActive(ctx); } }
客戶端啟動
packagetest01; importio.netty.bootstrap.Bootstrap; importio.netty.channel.ChannelFuture; importio.netty.channel.ChannelInitializer; importio.netty.channel.nio.NioEventLoopGroup; importio.netty.channel.socket.SocketChannel; importio.netty.channel.socket.nio.NioServerSocketChannel; importio.netty.channel.socket.nio.NioSocketChannel; /** * Created by wujiazhen on 2018/1/15. */ public classEchoClient { public static void main(String[] args){ newEchoClient().start(); } public void start(){ NioEventLoopGroup group =newNioEventLoopGroup(); try{ Bootstrap bootstrap =newBootstrap(); bootstrap.group(group) //區別與服務端的channel,客戶端用NioSocketChannel .channel(NioSocketChannel.class) .remoteAddress("127.0.0.1",2000) .handler(newChannelInitializer<SocketChannel>() { protected void initChannel(SocketChannel socketChannel)throwsException { socketChannel.pipeline().addLast(newEchoClientChannelHandler()); } }); ChannelFuture sync = bootstrap.connect().sync(); sync.channel().closeFuture().sync(); }catch(InterruptedException e) { e.printStackTrace(); }finally{ try{ group.shutdownGracefully().sync(); }catch(InterruptedException e) { e.printStackTrace(); } } } }