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

posted on 2019-11-20 18:16  sumlen  阅读(2377)  评论(0编辑  收藏  举报

导航