【一、初识Netty】

目标

这一系列文章会先通过官方网站的一些示例作为起始,后续会穿插一些本人项目中运用到的一些知识点和案例代码进去,帮助大家理解和使用Netty。如果时间充足会考虑用Netty实现一个应用示例。
本系列使用的是Netty4版本

什么是Netty

Netty 是一款高性能、异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。它极大地简化了 TCP 和 UDP 套接字服务器等网络编程的复杂性,使得开发人员可以专注于业务逻辑的实现,而无需过多关注底层网络编程的细节。

Netty官方文档

为什么使用Netty

使用Netty作为网络编程框架的原因有很多,以下是一些关键的考量点:

  1. 高性能:在构建高性能的网络应用时,Netty的异步非阻塞I/O模型能够显著提升吞吐量并降低延迟。Netty内部使用Reactor模式,这使得它能够同时处理成千上万的连接,而不会造成资源瓶颈。

  2. 简单易用:Netty的API设计简洁明了,降低了学习曲线,使开发者能够快速上手。同时,Netty提供了丰富的文档和示例代码,帮助开发者更好地理解框架的工作原理和最佳实践。

  3. 可扩展性:Netty的模块化设计允许开发者根据需求定制和扩展功能。通过ChannelHandler、Codec和Pipeline等组件的组合,开发者可以轻松实现自定义的协议、编解码逻辑和业务处理流程。

  4. 丰富的功能:Netty不仅提供了基本的TCP/UDP套接字支持,还提供了HTTP、WebSocket、SSL/TLS等高级功能的实现。这使得开发者无需从头开始编写这些复杂协议的实现代码,从而大大节省了开发时间。

  5. 稳定性和健壮性:Netty经过广泛的测试和优化,能够在各种网络环境下稳定运行。它提供了丰富的异常处理和容错机制,确保应用在网络波动或异常情况下仍能保持正常工作。

使用Netty构建一个简单的网络应用

这里我们引用官方的一个示例做解释

package io.netty.example.discard;
    
import io.netty.bootstrap.ServerBootstrap;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
    
/**
 * Discards any incoming data.
 */
public class DiscardServer {
    
    private int port;
    
    public DiscardServer(int port) {
        this.port = port;
    }
    
    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap(); // (2)
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class) // (3)
             .childHandler(new ChannelInitializer<SocketChannel>() { // (4)
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new DiscardServerHandler());
                 }
             })
             .option(ChannelOption.SO_BACKLOG, 128)          // (5)
             .childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
    
            // 绑定端口等待连接
            ChannelFuture f = b.bind(port).sync(); // (7)
    
            // 等待服务关闭,这里会阻塞同步等待
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
    
    public static void main(String[] args) throws Exception {
        int port;
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        } else {
            port = 8080;
        }
        new DiscardServer(port).run();
    }
}

上述示例代码中按编号作解释

  1. NioEventLoopGroup是一个处理I/O操作的多线程事件循环。Netty为不同类型的传输提供了各种EventLoopGroup实现。在本例中,我们正在实现一个服务器端应用程序,因此将使用两个NioEventLoopGroup。第一个,通常被称为 “boss”,接受处理服务器的连接事件。第二个通常被称为“worker”,一旦server接受连接并将接受的连接注册给worker,它就会处理后续连接的IO事件。
  2. ServerBootstrap是一个帮助类,用于创建Server。对应客户端使用的是Bootstrap。
  3. 指定handler,用NioServerSocketChannel类实例化以处理连接事件 。
  4. 指定连接的处理handler。ChannelInitializer是一个特殊的处理程序,用于配置新的handler。我们可以在里面通过Pipeline添加多个handler形成一个数据处理的流程处理我们的业务数据如DiscardServerHandler。
  5. 设置特定于通道实现的参数,keepAlive之类的套接字选项。
  6. option和childOption的区别;option用于设置接受传入连接的NioServerSocketChannel,及连接事件的处理。childOption用于设置父ServerChannel已接受连接的通道。
  7. 绑定服务端口等待连接

下面看示例中的handler代码

package io.netty.example.discard;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelHandlerAdapter;

public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1)

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)
        ((ByteBuf) msg).release(); // (3)
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
        cause.printStackTrace();
        ctx.close();
    }
}
  1. DiscardServerHandler扩展了ChannelInboundHandlerAdapter ,它是ChannelInboundHandler的一个实现,用于处理接收到的数据。
  2. 重写channelRead()事件处理程序方法。每当从客户端接收到新数据时,就会调用此方法并传入收到的消息。在本例中,接收到的消息的类型为ByteBuf(和Java Nio中的ByteBuffer不是一个东西, Netty做了更好的封装)。
  3. 实现DISCARD协议,其实就是忽略接收到的消息,不回复。ByteBuf是一个引用计数的对象,必须通过release()方法显式释放。
  4. 如果handler中产生异常会回调这里,通过ctx.close关闭连接

通过上面的示例代码可以用Netty简单实现一个网络程序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ThinkLess404

有问题可以私信交流

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值