maven netty5服務端與客戶端的構建


maven版本依賴

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>5.0.0.Alpha2</version>
</dependency>

服務端代碼的編寫順序。

  1. 得到 ServerBootstrap的對象,用來監聽客戶端
    ServerBootstrap serverBootstrap = new ServerBootstrap();  
  2. 創建兩個線程池
    EventLoopGroup boss = new NioEventLoopGroup();  
    EventLoopGroup worker = new NioEventLoopGroup();  
    

    boss用來對端口的監聽,worker對數據進行處理

  3. 設置工廠
    serverBootstrap.group(boss, worker);  
    serverBootstrap.channel(NioServerSocketChannel.class);  
  4. 設置,可以理解為netty3中的管道
    serverBootstrap.childHandler(new ChannelInitializer<Channel>() {
    
    				@Override
    				protected void initChannel(Channel channel) throws Exception {
    					/**
    					 * 將“上傳下載”數據裝飾成String類型
    					 */
    					channel.pipeline().addLast(new StringDecoder());
    					channel.pipeline().addLast(new StringEncoder());
    					// 要處理的Handler
    					channel.pipeline().addLast(new ServerHandler2());
    				}
    			});
  5. 設置TCP參數
    serverBootstrap.option(ChannelOption.SO_BACKLOG, 2048);// serverSocketchannel的設置,鏈接緩沖池的大小
    serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);// socketchannel的設置,維持鏈接的活躍,清除死鏈接
    serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true);// socketchannel的設置,關閉延遲發送
  6. 綁定端口
    ChannelFuture future = serverBootstrap.bind(new InetSocketAddress(9090));
  7. (等待)關閉客戶端
    Channel channel = future.channel();
    channel.closeFuture().sync();

    完整代碼如下:
    服務端:

    package com.netty5.server;
    
    import java.net.InetSocketAddress;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    
    /**
     * @author Chalmers 2016年2月20日 下午7:52:49
     */
    public class NettyServer2 {
    
        public static void main(String[] args) {
            // 得到ServerBootstrap對象
            ServerBootstrap serverBootstrap = new ServerBootstrap();
    
            // 創建線程池
            EventLoopGroup boss = new NioEventLoopGroup();
            EventLoopGroup worker = new NioEventLoopGroup();
    
            try {
                // 類似於Netty3中的工廠
                serverBootstrap.group(boss, worker);
                serverBootstrap.channel(NioServerSocketChannel.class);
    
                // 類似於Netty3中的管道
                serverBootstrap.childHandler(new ChannelInitializer<Channel>() {
    
                    @Override
                    protected void initChannel(Channel channel) throws Exception {
                        /**
                         * 將“上傳下載”數據裝飾成String類型
                         */
                        channel.pipeline().addLast(new StringDecoder());
                        channel.pipeline().addLast(new StringEncoder());
                        // 要處理的Handler
                        channel.pipeline().addLast(new ServerHandler2());
                    }
                });
    
                // 設置參數,TCP參數
                serverBootstrap.option(ChannelOption.SO_BACKLOG, 2048);// serverSocketchannel的設置,鏈接緩沖池的大小
                serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);// socketchannel的設置,維持鏈接的活躍,清除死鏈接
                serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true);// socketchannel的設置,關閉延遲發送
    
                // 綁定端口,並且返回ChannelFuture對象
                ChannelFuture future = serverBootstrap.bind(new InetSocketAddress(
                        9090));
    
                System.out.println("啟動服務器...");
    
                // 等待客戶端的關閉
                Channel channel = future.channel();
                // 要記得是closeFuture(),作用是等待服務端的關閉
                channel.closeFuture().sync();
                // 該條語句不會輸出,原因:上面沒有關閉...
                // System.out.println("客戶端已經關閉...");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                boss.shutdownGracefully();
                worker.shutdownGracefully();
            }
        }
    }
    
    class ServerHandler2 extends SimpleChannelInboundHandler<String> {
    
        @Override
        protected void messageReceived(ChannelHandlerContext arg0, String arg1)
                throws Exception {
            // 輸出接收到的數據
            System.out.println(arg1);
    
            // 向客戶端發送數據
            arg0.channel().writeAndFlush("hi");
        }
    
        /**
         * 
         */
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            super.channelActive(ctx);
            System.out.println("channelActive");
        }
    
        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            super.channelInactive(ctx);
            System.out.println("channelInactive");
        }
    }

    客戶端:

    package com.netty.client;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioSocketChannel;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    
    /**
     * @author Chalmers 2016年2月20日 下午8:31:25
     */
    public class Client {
    
        public static void main(String[] args) {
            Bootstrap bootstrap = new Bootstrap();
    
            EventLoopGroup worker = new NioEventLoopGroup();
    
            bootstrap.channel(NioSocketChannel.class);
            bootstrap.group(worker);
    
            bootstrap.handler(new ChannelInitializer<Channel>() {
    
                @Override
                protected void initChannel(Channel channel) throws Exception {
                    channel.pipeline().addLast(new StringEncoder());
                    channel.pipeline().addLast(new StringDecoder());
                    channel.pipeline().addLast(new ClientHandler());
                }
            });
    
            ChannelFuture future = bootstrap.connect("127.0.0.1", 9090);
    
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                System.out.print("輸入: ");
                try {
                    String line = br.readLine();
                    future.channel().writeAndFlush(line);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    class ClientHandler extends SimpleChannelInboundHandler<String> {
    
        @Override
        protected void messageReceived(ChannelHandlerContext arg0, String arg1)
                throws Exception {
            System.out.println("收到服務端發送的消息..." + arg1);
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            // TODO Auto-generated method stub
            super.channelActive(ctx);
        }
    
        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            // TODO Auto-generated method stub
            super.channelInactive(ctx);
        }
        
        
    }

    因為netty5與netty3的差別挺大,所以注意區分開。

    http://moonmonster.iteye.com/blog/2278672

     

    當然,因為本人水平有限,所以更詳細的解釋可見

    netty權威指南作者的博客

    http://www.infoq.com/cn/articles/netty-server-create


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM