Netty入门

Netty:
Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。
“快速”和“简单”并不用产生维护性或性能上的问题。Netty 是一个吸收了多种协议(包括FTP、SMTP、HTTP等各种二进制文本协议)的实现经验,并经过相当精心设计的项目。最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
第一个demon:
入门例子:采用echo协议,也就是客户端发送什么服务器就返回什么,服务器核心维护两个EventLoop,分别是bossgroup和workgroup,boosgroup主要负责完成TCP的三次握手,来完成和客户端的连接,workgroup主要负责服务器端的读写操作和编解码,具体如下:

服务器:主要功能就是监听指定端口,等待客户端连接发送消息并将其消息返回给客户端。

public class EchoServer {//netty服务器主程序和客户端主程序非常相似,但也有些许区别。
    private final  int port;
    public EchoServer(int port){//构造方法,设置服务的所监听端口
        this.port = port;
    }

    public static void main(String[] args) throws Exception {
        if(args.length !=1){
            System.out.println("参数错误");
            return;
        }
        String host = args[0];
        int port = Integer.parseInt(args[0]);
        new EchoServer(port).start();
    }
    public  void start() throws  Exception{
        final  EchoServerHandler echoServerHandler = new EchoServerHandler();//服务的业务逻辑
        EventLoopGroup bossgroup = new NioEventLoopGroup();//异步线程组
        EventLoopGroup workgroup = new NioEventLoopGroup();
        try {
            final ServerBootstrap serverBootstrap = new ServerBootstrap();//netty的服务启动简易引导类。
            serverBootstrap.group(bossgroup,workgroup).channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {//匿名内部类 服务器启动会调用此类进行初始化,添加项目相关Handler.
                        public  void initChannel(SocketChannel socketChannel) throws Exception {
                           // socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024));
                            socketChannel.pipeline().addLast(echoServerHandler);//添加业务逻辑Handler到管道pipeline中。
                        }
                    });
            ChannelFuture future = serverBootstrap.bind().sync();//异步地绑定服务器; 调用sync()方法阻塞 等待直到绑定完成
            future.channel().closeFuture().sync();//获取 Channel 的 CloseFuture,并 且阻塞当前线 程直到它完成
        }finally {
            bossgroup.shutdownGracefully();//优雅关闭
            workgroup.shutdownGracefully();
        }
    }
}
//服务端Handler
@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("ReadComplete");
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);//将未决消息冲刷到 远程节点,并且关 闭该 Channel
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("Read");
        ByteBuf byteBuf = (ByteBuf)msg;
        System.out.println("Server received:"+byteBuf.toString(CharsetUtil.UTF_8));
        ctx.write(byteBuf);//将接收到的消息 写给发送者,而 不冲刷出站消息
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("exception ");
        cause.printStackTrace();
        ctx.close();
    }
}

客户端:连接服务器并发送消息。


public class EchoClient {
    private  final String host;
    private  final  int port;
    public  EchoClient(String host,int port){
        this.host = host;
        this.port = port;
    }
    public  void start() throws Exception{
        EventLoopGroup group = new NioEventLoopGroup();
        try{
            io.netty.bootstrap.Bootstrap bootstrap = new io.netty.bootstrap.Bootstrap();
            bootstrap.group(group)//服务器所用引导类:Serverbootstrap,创建 Bootstrap 
// 指定 EventLoopGroup 以 处理客户端事件;需要适 用于 NIO 的实现 适用于 NIO 传输的 Channel 类型
                    .channel(NioSocketChannel.class)
                    .remoteAddress(new InetSocketAddress(host,port))//绑定连接的服务器地址
                    .handler(new ChannelInitializer<SocketChannel>() {//
                        public void initChannel(SocketChannel socketChannel) throws Exception {
                            //socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024));
                            socketChannel.pipeline().addLast(new EchoClientHandler());//客户端Handler
                        }
                    });
            ChannelFuture future = bootstrap.connect().sync();//连接到远程节点,阻 塞等待直到连接完成
            future.channel().closeFuture().sync();//阻塞回调函数
        }finally {
            group.shutdownGracefully();
        }

    }

    public static void main(String[] args) throws Exception {
        if(args.length !=2){
            System.out.println("参数错误");
            return;
        }
        String host = args[0];
        int port = Integer.parseInt(args[1]);
        new EchoClient(host,port).start();
    }
}
//客户端Handler
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {//连接处于活跃状态,下图有介绍
        System.out.println("Client:channelActive");

            ctx.writeAndFlush(Unpooled.copiedBuffer("Time", CharsetUtil.UTF_8));//给服务器发送消息

    }

    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
        System.out.println("Client:channelRead0:"+byteBuf.toString(CharsetUtil.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("Client:exeception");
        cause.printStackTrace();
        ctx.close();
    }
}

Channel生命周期
测试结果:客户端给服务器发送字符串:Time,服务器接收并返回。
服务器
客户端

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值