第一個netty程式

來源:互聯網
上載者:User

標籤:版本   apt   port   解碼   輔助   oss   unp   rbo   log   

  這是我剛開始學習netty寫的第一個demo,原準備照著《Netty權威指南》的入門demo敲一邊,等到我去下載jar包搭建環境的時候才發現Netty竟然沒有5.x版本,現在最高 4.1.9。一臉懵逼的我一搜才知道Netty從5.x退回到4.x,具體原因不清楚。4.x與5.x畢竟隔著一個大版本,中間各種異同不是我這種小白現在能搞懂的,還是照著官方的demo來吧。下面這個例子就是參照官網guide中的demo修改而成,大概的邏輯是client 向 server請求server時間並列印。

服務端代碼:

 1 public class TimeServerHandler extends ChannelInboundHandlerAdapter{ 2      3     /** 4      * 每個傳入的訊息都要調用 5      * */ 6     @Override 7     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{ 8         ByteBuf buf = (ByteBuf)msg; 9         try{10             byte[] req = new byte[buf.readableBytes()];11             buf.readBytes(req);12             String body = new String(req, "UTF-8");13             System.out.println("伺服器收到的請求:" + body);14             String time = "Query time ?".equals(body) ? new Date().toString() : "fail";15             ByteBuf resp = Unpooled.copiedBuffer(time.getBytes());16             ctx.write(resp);17         }finally{18             buf.release();19         }20     }21     22     //通知ChannelInboundHandlerAdapter 最後一次對channelRead()的調用是當前批量讀取中的最後一條訊息。23     @Override24     public void channelReadComplete(ChannelHandlerContext ctx) {25         /**26          * ctx.write(resp) 是將資訊寫到訊息佇列,而不是每次write就寫入SocketChannel27          * ctx.flush() 是將訊息發送隊列中的資訊寫到SocketChannel中發送給對方,28          * ctx.writeAndFlush(resp) 直接寫入SocketChannel29          * */30         ctx.flush();31     }32     33     //處理過程中出現的異常34     @Override35     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {36         cause.printStackTrace();37         ctx.close();38     }39     40 }

 

 1 public class TimeServer { 2     public void bind(int port) throws Exception{ 3         //NIO線程組,專門用於處理網路事件,本質是Reactor線程組。 4         EventLoopGroup bosser = new NioEventLoopGroup();//用於服務端接受用戶端的串連 5         EventLoopGroup worker = new NioEventLoopGroup();//用於進行SocketChannel的網路讀寫 6          7         try { 8             ServerBootstrap boot = new ServerBootstrap();//啟動NIO服務端的輔助啟動類,降低開發複雜度。 9             10             boot.group(bosser, worker)11             .channel(NioServerSocketChannel.class)12             .option(ChannelOption.SO_BACKLOG, 1024)//配置TCP參數13             .childHandler(new ChannelInitializer<SocketChannel>(){//用於處理網路IO事件(記錄日誌,對訊息進行編解碼)14                 @Override15                 protected void initChannel(SocketChannel ch) throws Exception {16                     ch.pipeline().addLast(new TimeServerHandler());17                 }18             });19             20             ChannelFuture cf = boot.bind(port).sync();//非同步地綁定伺服器,調用sync()方法阻塞等待直到綁定完成。21             cf.channel().closeFuture().sync();//擷取ChannelFuture,並且阻塞當前線程直到它完成。22         } finally{23             bosser.shutdownGracefully();//釋放所有資源24             worker.shutdownGracefully();25         }26         27     }28     29     30     public static void main(String[] args) {31         int port = 8080;32         try {33             new TimeServer().bind(port);34         } catch (Exception e) {35             e.printStackTrace();36         }37     }38 }

 

用戶端代碼:

 1 public class TimeClientHandler extends ChannelInboundHandlerAdapter{ 2      3     //在到伺服器的串連已經建立之後將被調用 4     @Override 5     public void channelActive(ChannelHandlerContext ctx){ 6         byte[] req = "Query time ?".getBytes(); 7         ByteBuf firstMessage = Unpooled.buffer(req.length); 8         firstMessage.writeBytes(req); 9         ctx.writeAndFlush(firstMessage);10     }11     12     //當從伺服器接受到一條訊息時被調用13     @Override14     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{15         ByteBuf buf = (ByteBuf)msg;16         byte[] resp = new byte[buf.readableBytes()];17         buf.readBytes(resp);18         String str = new String(resp, "UTF-8");19         System.out.println("伺服器時間 : "+ str);20     }21     22     @Override23     public void channelReadComplete(ChannelHandlerContext ctx) {24         ctx.flush();25     }26  27     //處理過程中出現的異常28     @Override29     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {30         cause.printStackTrace();31         ctx.close();32     }33       34 }

 

public class TimeClient {    public void connect(String host, int port) throws Exception{        EventLoopGroup group = new NioEventLoopGroup();        try{            Bootstrap boot = new Bootstrap();            boot.group(group).channel(NioSocketChannel.class)            .option(ChannelOption.TCP_NODELAY, true)            .handler(new ChannelInitializer<SocketChannel>() {                @Override                protected void initChannel(SocketChannel ch) throws Exception {                    ch.pipeline().addLast(new TimeClientHandler());                }                            });                        ChannelFuture cf = boot.connect(host, port).sync();            cf.channel().closeFuture().sync();        }finally{            group.shutdownGracefully();        }    }        public static void main(String[] args) {        final String host = "127.0.0.1";        final int port = 8080;        try {            new TimeClient().connect(host, port);        } catch (Exception e) {            System.out.println("用戶端" + Thread.currentThread().getId() + " 請求出現異常");        }                    }}

 

運行代碼:

入門demo完成了,接下來就是在這個demo的基礎上修改,後面的代碼我也會一一記錄。

第一個netty程式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.