首页 > 其他分享 >问:聊一下NIO模型在Netty框架中的用法?

问:聊一下NIO模型在Netty框架中的用法?

时间:2024-09-08 12:20:47浏览次数:12  
标签:Netty NIO netty 用法 io new import channel

1. 核心概念和特点

Netty 是一个基于Java NIO(Non-blocking I/O)的高性能网络应用框架,它简化了网络编程,如TCP和UDP套接字服务器的开发。Netty的核心概念包括:

  • Channel:Netty中的基本I/O操作抽象。Channel表示一个打开的连接,可以进行读写操作。
  • EventLoop:负责处理Channel上的事件。EventLoop是一个单线程的执行器,它会为一个或多个Channel服务。
  • ChannelHandler:用于处理网络事件。可以将多个ChannelHandler链接在一起,形成一个ChannelPipeline。
  • ChannelFuture:Netty中所有I/O操作都是异步的,ChannelFuture提供了检测操作状态是否完成的方法。
  • Bootstrap/ServerBootstrap:这两个类用于简化Channel的配置和启动过程。

Netty的NIO模型特点包括:

  • 异步非阻塞:所有的I/O操作都是异步的,不会阻塞当前线程。
  • 事件驱动:通过事件循环(EventLoop)来处理Channel上的事件。
  • 高性能:通过零拷贝、线程池等技术提高性能。
  • 可扩展性:通过ChannelHandler可以轻松地扩展功能。
2. 示例:使用NIO模型进行网络通信和数据处理

下面是的Netty服务器和客户端示例,展示如何使用NIO模型进行网络通信和数据处理。

服务器端代码

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.buffer.ByteBuf;
import io.netty.util.CharsetUtil;

public class NettyServer {

    public static void main(String[] args) throws InterruptedException {
        // 创建事件循环组
        EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 用于接收连接
        EventLoopGroup workerGroup = new NioEventLoopGroup(); // 用于处理I/O操作

        try {
            // 创建服务器启动辅助类
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class) // 指定使用NIO传输Channel
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() {
                         @Override
                         protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
                             System.out.println("Server received: " + msg.toString(CharsetUtil.UTF_8));
                             // 回写数据给客户端
                             ctx.writeAndFlush(msg);
                         }
                     });
                 }
             });

            // 绑定端口并启动服务器
            ChannelFuture f = b.bind(8080).sync();
            f.channel().closeFuture().sync(); // 等待服务器关闭
        } finally {
            // 关闭事件循环组
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

客户端代码

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;

public class NettyClient {

    public static void main(String[] args) throws InterruptedException {
        // 创建事件循环组
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            // 创建客户端启动辅助类
            Bootstrap b = new Bootstrap();
            b.group(group)
             .channel(NioSocketChannel.class) // 指定使用NIO传输Channel
             .handler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() {
                         @Override
                         protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
                             System.out.println("Client received: " + msg.toString(CharsetUtil.UTF_8));
                         }

                         @Override
                         public void channelActive(ChannelHandlerContext ctx) throws Exception {
                             // 发送数据给服务器
                             ctx.writeAndFlush(Unpooled.copiedBuffer("Hello, Netty!", CharsetUtil.UTF_8));
                         }
                     });
                 }
             });

            // 连接服务器
            ChannelFuture f = b.connect("localhost", 8080).sync();
            f.channel().closeFuture().sync(); // 等待客户端关闭
        } finally {
            // 关闭事件循环组
            group.shutdownGracefully();
        }
    }
}
3. NIO模型在网络编程中的优势及场景

优势

  • 高性能:通过异步非阻塞I/O和事件驱动机制,能够高效地处理大量并发连接。
  • 低资源消耗:通过线程池和零拷贝等技术,减少了资源消耗。
  • 高可扩展性:通过ChannelHandler可以轻松地扩展功能,实现复杂的网络应用。
  • 稳定性:Netty经过了长时间的验证和优化,具有高度的稳定性。

应用场景

  • 高性能服务器:如HTTP服务器、WebSocket服务器、游戏服务器等。
  • 微服务架构:作为微服务之间的通信框架,提供高效的RPC(远程过程调用)支持。
  • 实时系统:如推送系统、即时通讯系统等需要低延迟和高并发的场景。
4. 结尾

Netty是一个基于Java NIO的高性能网络应用框架,它通过异步非阻塞I/O、事件驱动机制和高效的线程模型,提供了高性能、低资源消耗、高可扩展性和稳定性的网络编程解决方案。

标签:Netty,NIO,netty,用法,io,new,import,channel
From: https://blog.csdn.net/li_guolin/article/details/142024845

相关文章

  • MinIO基础配置及应用-.net 8
    MinIO是一种常见的对象存储的服务器,可以用来搭建网盘等服务。在本人配置MinIO环境时遇到过一些问题,在此处记录以下配置过程。本次配置使用docker进行。1.在电脑上安装和配置docker(我的服务器电脑是deepin系统,上面安装了宝塔面板)具体安装步骤在网上搜索即可,deepin官方有个wiki,里......
  • Netty权威指南:Netty总结-Java I/O
    第一章JavaI/O1.1I/O基础入门Java1.4之前的版本,开发高性能I/O程序的时候,有问题:没有数据缓冲区,I/O性能有问题没有Channel概念,只有输入输出流只有BIO,通常会导致通信线程被长时间阻塞支持字符集有限,硬件移植性不好1.1.1Linux网络I/O模型Linux的内核将所有的外部设备都......
  • 这些ES6用法你都会吗?
    一关于取值取值在程序中非常常见,比如从对象obj中取值constobj={a:1b:2c:3d:4}吐槽:consta=obj.a;constb=obj.b;constc=obj.c;//或者constf=obj.a+obj.b;constg=obj.c+obj.d;改进:用ES6解构赋值const{a,b,c,d}=obj......
  • minio上传文件
    0Linux部署Minio0.1获取MinIO安装包MinIO官网:https://min.io/下载地址如下:https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20230809233022.0.0.x86_64.rpm通过以下命令可直接将安装包下载至服务器wgethttps://dl.min.io/server/minio/release/linux-a......
  • Netty核心组件详解
    目录一、Netty使用和常用组件Netty的优势为什么不用Netty5为什么Netty使用NIO而不是AIO?为什么不用Mina?Bootstrap、EventLoop(Group)、Channel事件和ChannelHandler、ChannelPipelineChannelFuture第一个Netty程序二、Netty组件了解EventLoop和Eve......
  • crypto插件的用法
    文章目录1.概念介绍2.方法与功能2.1基本用法2.2加密算法3.示例代码4.内容总结我们在上一章回中介绍了"FlutterCacheManager组件"相关的内容,本章回中将介绍一个加密工具包.闲话休提,让我们一起TalkFlutter吧。1.概念介绍加密主要是为了保护一些重要数据,我......
  • Dotnetty学习笔记——自定义初始化处理器
    常常我们需要开一个服务单,对接不同的客户端,编码器、解码器等都不同,需要针对不同IP添加不同的处理器。publicclassCustomInitializer:Channellnitializer<lSocketChannel>{Action<string,string>_dealMsgAction;lServer_server;publicCustomInitializer(Action<st......
  • python PaddleOCR库用法及知识点详解
    识别图片的设置https://blog.csdn.net/f2315895270/article/details/128147744?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-128147744-blog-89082526.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_in......
  • 一文了带您了解 ES6 Class 用法
    文章目录一、概述二、用法2.1基础用法2.2封装与继承2.3继承一、概述ES6中的class是基于JavaScript中的一个强大的属性,也就是原型属性prototype,由这个属性改良得来的一种语法糖。在ES6中,class(类)作为对象的模板被引入,可以通过class关键字定义类。class的本......
  • 抓包工具tcpdump用法说明
    tcpdump采用命令行方式对接口的数据包进行筛选抓取,其丰富特性表现在灵活的表达式上。不带任何选项的tcpdump,默认会抓取第一个网络接口,且只有将tcpdump进程终止才会停止抓包。例如:shell>tcpdump-nn-ieth0icmp下面是详细的tcpdump用法。1.1tcpdump选项它的命令格式......