• netty入门


    一。用netty创建server

      

    package com.cw.demo.netty.server;
    
    import com.cw.demo.netty.server.channelhandler.EchoServerHandler;
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    
    
    /**
     * @author  chenwei
     * Created by chenwei01 on 2017/4/24.
     * 1.创建ServerBootstrap实例来引导绑定和启动服务器
     * 2.创建NioEventLoopGroup对象来处理事件,如接受新连接、接收数据、写数据等等
     * 3.指定InetSocketAddress,服务器监听此端口
     * 4.设置childHandler执行所有的连接请求
     * 5.都设置完毕了,最后调用ServerBootstrap.bind() 方法来绑定服务器
     */
    public class EchoServer {
    
        private  int port;
    
        public EchoServer(int port){
            this.port=port;
        }
    
        public void start() throws  Exception{
            //因为使用NIO,指定NioEventLoopGroup来接受和处理新连接
            EventLoopGroup group = new NioEventLoopGroup();
            //创建bootstrap来启动服务器
            ServerBootstrap boot = new ServerBootstrap();
            boot.group(group).
                    //指定通道类型为NioServerSocketChannel
                            channel(NioServerSocketChannel.class).
                            localAddress(port).
                       //调用childHandler用来指定连接后调用的ChannelHandler
                            childHandler(new ChannelInitializer<Channel>() {
                           //这个方法传ChannelInitializer类型的参数,ChannelInitializer是个抽象类,所以需要实现initChannel方法,这个方法就是用来设置ChannelHandler
                           @Override
                           protected void initChannel(Channel channel) throws Exception {
                               channel.pipeline().addLast(new EchoServerHandler());
                           }
                       });
            ChannelFuture future=boot.bind().sync();
            System.out.println( EchoServer.class.getName()+" started and listen on "+future.channel().localAddress());
            future.channel().closeFuture().sync();
    
    
        }
    
    
        public static void main(String[] args) {
            EchoServer server=new EchoServer(20000);
            try {
                server.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    创建 ChannelHandler,实际上 ChannelHandler 处理实际业务的主要代码

    package com.cw.demo.netty.server.channelhandler;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import io.netty.util.ReferenceCountUtil;
    
    import java.nio.charset.Charset;
    /**
     *   Netty中有两个方向的数据流,上图显示的入站(ChannelInboundHandler)和出站(ChannelOutboundHandler)之间有一个明显的区别:
     *   若数据是从用户应用程序到远程主机则是“出站(outbound)”,
     *   相反若数据时从远程主机到用户应用程序则是“入站(inbound)”。
     *   为了使数据从一端到达另一端,一个或多个ChannelHandler将以某种方式操作数据。
     *   这些ChannelHandler会在程序的“引导”阶段被添加ChannelPipeline中,并且被添加的顺序将决定处理数据的顺序。
     *   ChannelPipeline的作用我们可以理解为用来管理ChannelHandler的一个容器,每个ChannelHandler处理各自的数据(例如入站数据只能由ChannelInboundHandler处理),
     *   处理完成后将转换的数据放到ChannelPipeline中交给下一个ChannelHandler继续处理,直到最后一个ChannelHandler处理完成。
     */
    
    /**
     * @author  chenwei
     * Created by chenwei01 on 2017/4/25.
     *  Netty使用多个Channel Handler来对事件处理的分离,因为可以很容的添加、更新、删除业务逻辑处理handler
     *  它的每个方法都可以被重写,它的所有的方法中只有channelRead方法是必须要重写的。
     */
    public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    
    
    
        //重写该方法,该方法会被调用用来接收数据
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            System.out.println("Server reveived: " + ((ByteBuf) msg).toString(Charset.forName("UTF-8")));
            Channel channel = ctx.channel();
    
            channel.writeAndFlush(Unpooled.buffer().writeBytes("我收到了".getBytes("UTF-8")));
            ReferenceCountUtil.release(msg);
        }
    
        @Override
        public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
            Channel channel = ctx.channel();
    
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    
    
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }

    二。客户端测试

      客户端代码与服务端代码大致类似,不过是启动类用了 Bootstrap 而不是 ServerBootstrap

      或者最简单的,用telnet 来测试 刚才写的nettyServer

      

  • 相关阅读:
    教学计划-物理必修二
    小白学习Python之路---开发环境的搭建
    解决pycharm连接MySQL 1366报错的问题
    Leetcode 118 杨辉三角
    Leecode 70 爬楼梯
    RabbitMQ
    Leetcode 38 报数
    Leecode 69 x的平方根
    select 实现server I/O多路复用通信
    Leetcode 67 二进制求和
  • 原文地址:https://www.cnblogs.com/manmanrenshenglu/p/9013346.html
Copyright © 2020-2023  润新知