【java网络编程】netty框架

article/2025/9/21 11:04:58

一、简介

netty是一个高性能、异步事件驱动的NIO框架,它基于Java Nio提供的API实现,提供了对TCP、UDP和文件传输的支持。

二、Reactor模型

Reactor是一种并发处理客户端请求响应的事件驱动模型。服务端在接收到客户端请求后采用多路复用策略,通过一个非阻塞的线程来异步接收所有的客户端请求。

(1)Reactor单线程模型

一个线程负责建立连接、读、写等操作。如果在业务中处理中出现了耗时操作,就会导致所有请求全部处理延时。

 (2)Reactor多线程模型

只是在单线程的模型情况下,使用线程池管理多个线程,用多线程进行处理业务。

(3)Reactor主从多线程模型

该模型采用一个主Reactor仅处理连接,而多个子Reactor用于处理IO读写。然后交给线程池处理业务。Tomcat就是采用该模式实现。效率高

三、Netty的核心组件

(1)BootStrap/ServerBootStrap

BootStrap用于客户端服务启动。ServerBootStrap用于服务端启动。

(2)NioEventLoop

基于线程队列的方式执行事件操作,具体要执行的事件操作包括连接注册、端口绑定和I/O数据读写等。每个NioEventLoop线程都负责多个Channel的事件处理。

(3)NioEventLoopGroup

对NioEventLoop的生命周期进行管理

(4)Future/ChannelFuture

用于异步通信的实现,基于异步通信方式可以在I/O操作触发后注册一个事件,在I/O操作(数据读写完成或失败)完成后自动触发监听事件并完成后续操作。

(5)Channel

是netty中的网络通信组件,用于执行具体的I/O操作。主要功能包括:网络连接的建立、连接状态的管理、网络连接参数的配置、基于异步NIO的网络数据操作。

(6)Selector

用于I/O多路复用中Channel的管理

(7)ChannelHandlerContext

Channel上下文信息的管理。每个ChannelHandler都对应一个ChannelHandlerContext。

(8)ChannelHandler

I/O事件的拦截和处理。

其中ChannelInBoundHandler用于处理数据接收的I/O操作。

其中ChannelOutBoundHandler用于处理数据发送的I/O操作。

(9)ChannelPipeline

基于拦截器设计模式实现的事件拦截处理和转发。

每个Channel都对应一个ChannelPipeline,在ChannelPipeline中维护了一个由ChannelHandlerContext组成的双向链表,每个ChannelHandlerContext都对应一个ChannelHandker,以完成具体Channel事件的拦截和处理。

四、netty的运行原理

Server工作流程:

1、server端启动时绑定本地某个端口,初始化NioServerSocketChannel.

2、将自己NioServerSocketChannel注册到某个BossNioEventLoopGroup的selector上。

server端包含1个Boss NioEventLoopGroup和1个Worker NioEventLoopGroup

Boss NioEventLoopGroup专门负责接收客户端的连接,Worker NioEventLoopGroup专门负责网络的读写。

NioEventLoopGroup相当于1个事件循环组,这个组里包含多个事件循环NioEventLoop,每个NioEventLoop包含1个selector和1个事件循环线程。

BossNioEventLoopGroup循环执行的任务:

  1. 轮询accept事件;
  2. 处理accept事件,将生成的NioSocketChannel注册到某一个WorkNioEventLoopGroup的Selector上。
  3. 处理任务队列中的任务,runAllTasks。任务队列中的任务包括用户调用eventloop.execute或schedule执行的任务,或者其它线程提交到该eventloop的任务。

WorkNioEventLoopGroup循环执行的任务:

  1. 轮询read和Write事件
  2. 处理IO事件,在NioSocketChannel可读、可写事件发生时,回调(触发)ChannelHandler进行处理。
  3. 处理任务队列的任务,即 runAllTasks

五、netty怎么解决粘包拆包的

使用解码器解决,解码器一个有4种

 ch.pipeline().addLast(new LengthFieldBasedFrameDecoder());
  1. 固定长度的拆包器 FixedLengthFrameDecoder , 每个应用层数据包的拆分都是固定长度大小
  2. 行拆包器 LineBasedFrameDecoder ,每个应用层数据包,都以换行符作为分隔符,进行分割拆分
  3. 分隔符拆包器 DelimiterBasedFrameDecoder ,每个应用层数据包,都通过自定义分隔符,进行分割拆分
  4. 基于数据包长度的拆包器,LengthFieldBasedFrameDecoder 将应用层数据包的长度,作为接收端应用层数据包的拆分依据。(常用)

六、netty性能为什么这么高

(1)网络模型(I/O多路复用模型)

多路复用IO,采用一个线程处理连接请求,多个线程处理IO请求,他比BIO能处理更多请求,数据请求和数据处理都是异步,底层采用了linux的select、poll、epoll

(2)数据零拷贝

netty的数据接受和发送均采用对外直接内存进行socket读写,堆外内存可以直接操作系统内存,不需要来回的进行字节缓冲区的二次复制。同时netty提供了组合buffer对象,可以避免传统通过内存复制的方式合并buffer时带来的性能损耗。

netty文件传输采用transfeTo方法操作,完全零拷贝。

(3)内存重用机制

使用堆外直接内存,重用缓冲区,不需要jvm回收内存

(4)无锁设计

netty内部采用串行无锁化设计对I/O操作,避免多线程竞争CPU和资源锁定导致的性能下降。

(5)高性能的序列化框架

使用google的protoBuf实现数据的序列化

(6)使用FastThreadLocal类

使用FastThreadLocal类替代ThreadLocal类

七、netty使用

1、引入依赖

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

2、编写服务端代码(固定写法)

public class Server {  private int port;  public Server(int port) {  this.port = port;  }  public void run() {  EventLoopGroup bossGroup = new NioEventLoopGroup(); //用于处理服务器端接收客户端连接  EventLoopGroup workerGroup = new NioEventLoopGroup(); //进行网络通信(读写)  try {  ServerBootstrap bootstrap = new ServerBootstrap(); //辅助工具类,用于服务器通道的一系列配置  bootstrap.group(bossGroup, workerGroup) //绑定两个线程组  .channel(NioServerSocketChannel.class) //指定NIO的模式  .childHandler(new ChannelInitializer<SocketChannel>() { //配置具体的数据处理方式  @Override  protected void initChannel(SocketChannel socketChannel) throws Exception {  socketChannel.pipeline().addLast(new ServerHandler());  }  })  /** * 对于ChannelOption.SO_BACKLOG的解释: * 服务器端TCP内核维护有两个队列,我们称之为A、B队列。客户端向服务器端connect时,会发送带有SYN标志的包(第一次握手),服务器端 * 接收到客户端发送的SYN时,向客户端发送SYN ACK确认(第二次握手),此时TCP内核模块把客户端连接加入到A队列中,然后服务器接收到 * 客户端发送的ACK时(第三次握手),TCP内核模块把客户端连接从A队列移动到B队列,连接完成,应用程序的accept会返回。也就是说accept * 从B队列中取出完成了三次握手的连接。 * A队列和B队列的长度之和就是backlog。当A、B队列的长度之和大于ChannelOption.SO_BACKLOG时,新的连接将会被TCP内核拒绝。 * 所以,如果backlog过小,可能会出现accept速度跟不上,A、B队列满了,导致新的客户端无法连接。要注意的是,backlog对程序支持的 * 连接数并无影响,backlog影响的只是还没有被accept取出的连接 */  .option(ChannelOption.SO_BACKLOG, 128) //设置TCP缓冲区  .option(ChannelOption.SO_SNDBUF, 32 * 1024) //设置发送数据缓冲大小  .option(ChannelOption.SO_RCVBUF, 32 * 1024) //设置接受数据缓冲大小  .childOption(ChannelOption.SO_KEEPALIVE, true); //保持连接  ChannelFuture future = bootstrap.bind(port).sync();  future.channel().closeFuture().sync();  } catch (Exception e) {  e.printStackTrace();  } finally {  workerGroup.shutdownGracefully();  bossGroup.shutdownGracefully();  }  }  public static void main(String[] args) {  new Server(8379).run();  }  
}  

 3、编写Handler处理类


public class ServerHandler  extends ChannelHandlerAdapter {  @Override  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  //do something msg  ByteBuf buf = (ByteBuf)msg;  byte[] data = new byte[buf.readableBytes()];  buf.readBytes(data);  String request = new String(data, "utf-8");  System.out.println("Server: " + request);  //写给客户端  String response = "我是反馈的信息";  ctx.writeAndFlush(Unpooled.copiedBuffer("888".getBytes()));  //.addListener(ChannelFutureListener.CLOSE);  }  @Override  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  cause.printStackTrace();  ctx.close();  }  }  


http://chatgpt.dhexx.cn/article/Jyh4NFWN.shtml

相关文章

Netty学习二:Netty整体框架

一、Netty的整体结构和源码结构 1. Core层 提供底层网络通信的通用抽象和实现&#xff0c;包括可扩展的事件模型、通用的通信API和支持零拷贝的ByteBuf等。 common模块是Netty的核心基础包&#xff0c;提供丰富的工具类&#xff0c;其他模块都需要依赖该模块。常用的包括&…

Netty框架

概述 Netty 是由 JBOSS 提供的一个 Java 开源框架。Netty 提供异步的、基于事件驱动的网络应用程序框架&#xff0c;用以快速开发高性能、高可靠性的网络 IO 程序。 Netty 是一个基于 NIO 的网络编程框架&#xff0c;使用 Netty 可以帮助你快速、简单的开发出一个网络应用&…

Netty框架基本介绍

NIO 1.概述&#xff1a;NIO全称java non-blocking IO &#xff0c;是指JDK1.4开始&#xff0c;java提供了一系列改进的输入/输出的新特性&#xff0c;被统称为NIO(即New IO )。新增了许多用于处理输入输出的类&#xff0c;这些类都被放在java.nio包及子包下&#xff0c;并且对j…

超详细Netty入门,看这篇就够了!

思维导图 前言 本文主要讲述Netty框架的一些特性以及重要组件&#xff0c;希望看完之后能对Netty框架有一个比较直观的感受&#xff0c;希望能帮助读者快速入门Netty&#xff0c;减少一些弯路。 一、Netty概述 官方的介绍&#xff1a; Netty is an asynchronous event-drive…

SPI通信协议详解(一)

SPI是一个同步的数据总线&#xff0c;也就是说它是用单独的数据线和一个单独的时钟信号来保证发送端和接收端的完美同步。 时钟是一个振荡信号&#xff0c;它告诉接收端在确切的时机对数据线上的信号进行采样。 产生时钟的一侧称为主机&#xff0c;另一侧称为从机。总是只有一个…

SPI协议的介绍

学习内容&#xff1a; 学习SPI协议记录 学习清单&#xff1a; 提示&#xff1a;这里可以添加要学的内容 例如&#xff1a; SPI协议的介绍三根线还是四根线两个概念四种模式SPI时序图SPI优缺点SPI和IIC的对比 学习详细内容&#xff1a; 1.SPI协议的介绍 SPI是串口外设接口…

SPI 通信协议

文章目录 【 1. 概述 】【 2. 原理 】1. 全双工特征下的传输特点2. 二线式、三线式的SPI3. SPI 模式CPOL(Clock Polarity)&#xff0c;时钟极性CPHA (Clock Phase)&#xff0c;时钟相位通信模式_时序 4. 通信过程5. 底层数据传输演示 【 3. SPI底层驱动 】 【 1. 概述 】 SPI …

SPI通信协议基础

文章目录 引言正文串行与并行通信SPI通信简介SPI如何运作&#xff1f;时钟从机选择多个从机MOSI和MISOSPI数据传输步骤 SPI的优缺点优点缺点 好文推荐参考 引言 当您将微控制器连接到传感器&#xff0c;显示器或其他模块时&#xff0c;您是否考虑过这两种设备如何相互通信&…

SPI、I2C、UART(即串口)三种串行总线详解

以下内容均来源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 几个串口协议学习整理 UART IIC SPI_mainn的博客-CSDN博客 SPI、I2C、UART三种串行总线的原理、区别及应用_嵌入式Linux,的博客-CSDN博客 RS-232 和 UART 之间有什么区别&#xff1f; - 知乎…

uart、spi、i2c通信协议详解

文章目录 前言一、uart&#xff08;串口&#xff09;介绍使用rs232、rs485拓展 二、I2C介绍1.宏观流程2.时序上3.典型操作 三、spi&#xff08;串行外设接口&#xff09;介绍使用1.宏观上2.微观上 总结1.i2c和spi对比 前言 之前对于各种通信协议学习了就忘&#xff0c;学了就忘…

普通GPIO模拟SPI通信协议(软件SPI)

在工作中偶尔会遇到SPI不够用的情况&#xff0c;而我们又要去使用SPI通信协议&#xff0c;此时就需要我们自己去模拟SPI通信协议。我们知道SPI通信协议有四种模式&#xff0c;它们分别如下所示&#xff1a; 下面是我基于ATSAM4SD16B芯片在Atmel Studio上用普通GPIO模拟的SPI…

SPI 协议

一. 概念 1. 通常SPI通信要求4根线&#xff0c;分别是MOSI(mast output salve input), MISO, CLK, CS。 2. 当发送和接受数据的工作都准备好了&#xff0c;只要有时钟CLK,就发送数据&#xff0c;没有时钟就不发送&#xff0c;而且一个时钟周期发送一位(bit)数据&#xff0c;所…

SPI通信协议(SPI总线)学习

转载自&#xff1a;https://www.cnblogs.com/deng-tao/p/6004280.html 1、什么是SPI&#xff1f; SPI是串行外设接口(Serial Peripheral Interface)的缩写。是 Motorola 公司推出的一 种同步串行接口技术&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总…

SPI通信

1 SPI的简介及基本特点 1 SPI的简单介绍 最近工作中使用了SPI通信方式来做TM4C129和STM32之间的通信&#xff0c;为了更好地解决问题就学习了SPI原理的相关内容&#xff0c;完成了项目之后&#xff0c;也对这种通信方式有了较为深入的了解&#xff0c;现在来对SPI的使用方法进…

详解SPI通信协议

一、SPI简介 SPI&#xff0c;即Serial Peripheral Interface的英文缩写。从字面意思看就是串行外部设备接口&#xff0c;是一种全双工、高速、同步的通信总线。 SPI最早是摩托罗拉公司开发的全双工同步串行总线&#xff0c;用于微控制器&#xff08;MCU&#xff09;连接外部设…

stm32中常见的通信协议之SPI

目录 1.SPI总线2.SPI的寻址方式3.SPI的工作原理总结4.SPI的通讯过程5.SPI的极性和相位6.IIC和SPI的异同7.stm32中SPI配置中常用的寄存器8.stm32中相关库函数 1.SPI总线 SPI是串行外设接口的缩写&#xff0c;SPI是一种高速的、全双工、同步的串行通信协议&#xff1b;SPI采用主…

【通信协议】一文搞懂SPI

SPI总线简介 SPI(Serial Peripheral Interface)是 Motorola 公司推出的一种同步串行接口技术&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线。 接口定义 SPI接口共有4根信号线&#xff0c;分别是&#xff1a;片选信号、时钟信号、串行输出信号、串行…

SPI 通信协议 最详细解读!!!

SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外围接口&#xff09;是一种高速、全双工、同步的通信总线&#xff0c;主要应用在EEPROM、FLASH、实时时钟、AD转换器上&#xff0c;以及数字信号处理器和数字信号解码器之间。 信号线 SPI有四根信号线&#xff1a;…

SPI 通信协议详解

SPI通信协议详解 写在最前: 本文讲述了SPI通信协议的基本内容包括如下 SPI的基础知识SPI的读写时序 本文重点参考 英文维基百科 中文维基百科 百度百科 注意: 倘若读者有足够的耐心和英文水平&#xff0c;强烈建议自行去英文维基百科去阅读相关知识。 相关链接&#xff1a; SPI…

通信协议篇——SPI通信

通信协议篇——SPI通信 1.简介 SPI&#xff08;Serial Peripheral Interface&#xff09;是一种高速、同步、全双工串行通信总线&#xff0c;采用主从机通信模式&#xff0c;主要应用在EEPROM&#xff0c;FLASH&#xff0c;实时时钟&#xff0c;AD转换器等。 2.原理 通信方…