(1)Netty简单的编写一个Netty入门程序

Netty学习之路!记录每周学习到的netty!

LZ为什么要学习Netty呢,其实LZ自己也不知道。

进入正题;

Netty 是由NIO进化而来的,它是一个很底层的框架,底层基于NIO。而NIO又是IO的一个升级。

所以他们的顺序是IO,NIO,Netty。

Netty他是一个通讯的框架。

其实有很多很多的框架,技术底层都用到了Netty,这个可以在Netty官网上看到。

举一些知名的项目也是前三的:AkkaApache BookKeeperApache Cassandra,这些项目都是Apache的。项目的具体我就不做多介绍了,(PS:其实LZ也不知道,所以介绍不了  Hhhhhhh)不过大家可以去Netty的官网上面看看。

Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端,Netty是一个NIO客户端服务器的框架,可以快速的开发协议服务器和客户端登网络应用程序。极大的简化了TCP和UDP套接字服务器等网络编程。Netty经过精心的设计,具有很多丰富的协议,如:FTP,SMTP,HTTP以及各种基于二进制和基于文本的传统协议,因此,Nett'y成功地找到了一种不在被妥协的情况下实现易于开发,性能,稳定性和灵活方法的方法。(PS:Netty里面封装了各种协议,各种API,基本上能说得出口的协议,Netty基本都集成了。说白话就是简易了开发,让我们程序员更轻松。)

关于性能方面:

1:更高的吞吐量

2:减少资源消耗

3:最小化不必要的内存复制

关于安全方面:

完整的SSL/TLS和StartTLS的支持

下面的是官网的一张图:由于LZ看的不是很透彻,所以就不做讲解了。

接下来进入代码环节:

首先导入包: 

"io.netty:netty-all:4.1.10.Final"

LZ这里用的是Gradle,所以和maven的不一样,下面贴一下Maven的:

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.10.Final</version>
</dependency>

首先我们来编写一个Netty的服务器:

public static void main(String[] args) throws Exception {
        // 从客户端接收链接,不做处理
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        // 接收链接  分发链接
        EventLoopGroup worketGroup = new NioEventLoopGroup();
        try {
            // 启动服务端
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, worketGroup)
                    // 通道  通过反射的方式
                    .channel(NioServerSocketChannel.class)
                    // 指定日志级别
                    .handler(new LoggingHandler(LogLevel.INFO))
                    // 定义处理器
                    .childHandler(new WebSocketChannelInitializer());

            ChannelFuture sync = bootstrap.bind(new InetSocketAddress(8899)).sync();
            sync.channel().closeFuture().sync();
        } finally {
            // 优雅关闭
            bossGroup.shutdownGracefully();
            worketGroup.shutdownGracefully();
        }
    }

 LZ就不过多解释:代码都写好注释了。

然后就是书写初始化类(PS:看继承的类大家就应该都知道了,这是一个初始化的类):  里面的方法LZ就不过多介绍,不然篇幅太长;

public class MyClientInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        // AddLast的意思是添加到末尾    主要是解码  
        pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
        pipeline.addLast(new LengthFieldPrepender(4));
        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
        // 添加砸门自己定义的处理器
        pipeline.addLast(new MyServerHandler());

    }
}

之后当然是书写自己定义的处理器类

public class MyServerHandler extends SimpleChannelInboundHandler<String> {



    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        // 打印收到的语句
        System.out.println(ctx.channel().remoteAddress()+","+msg);
        // 服务端像客户端返回一段话 加上UUID
        ctx.channel().writeAndFlush("form server:"+ UUID.randomUUID());


    }
}

到这里服务端基本算是写完了,接下来就是书写客户端。

  public static void main(String[] args) throws InterruptedException {
        EventLoopGroup eventExecutors = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(eventExecutors)
                    .channel(NioSocketChannel.class)
                    .handler(new MyClientInitializer());
            ChannelFuture channelFuture = bootstrap.connect("localhost", 8899).sync();
            channelFuture.channel().closeFuture().sync();
        }finally {
            eventExecutors.shutdownGracefully();
        }


    }

客户端这里为什么是创建一个呢。目前呢不要太在乎细节,LZ后面会讲。

接下来是书写客户端初始类:

public class MyClientInitializer extends ChannelInitializer<SocketChannel> {


    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
        pipeline.addLast(new LengthFieldPrepender(4));
        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
        pipeline.addLast(new MyClientHandler());

    }
}

在下面就是客户端处理器类:

public class MyClientHandler extends SimpleChannelInboundHandler<String> {


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println(ctx.channel().remoteAddress());
        System.out.println("client output" + msg);
        // 向服务端返回时间
        ctx.writeAndFlush("from client"+ LocalDateTime.now());
    }
}

现在一个很简单的程序就算是写完了。

其实大家仔细一点都看出来了,服务端的代码和客户端的代码基本差不多,大同小异。

具体的运行结果LZ就不做过多的演示了。

以后LZ会将每周学到的Netty知识,写到博客中。
 

学而时习之,不亦乐乎。 送给大家的一句话,也送给我自己的一句话。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值