netty之基础aio,bio,nio

前言


在Java中,提供了一些关于使用IO的API,可以供开发者来读写外部数据和文件,我们称这些API为Java IO。IO是Java中比较重要知识点,且比较难学习的知识点。并且随着Java的发展为提供更好的数据传输性能,目前有三种IO共存;分别是BIO、NIO和AIO。
在这里插入图片描述
同步阻塞I/O模式
是一个比较传统的通信方式,模式简单,使用方便。但并发处理能力低,通信耗时,依赖网速。
同步非阻塞模式
NIO 与原来的 I/O 有同样的作用和目的, 他们之间最重要的区别是数据打包和传输的方式。原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。
异步非阻塞I/O模型
是一种非阻塞异步的通信模式。在NIO的基础上引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。

aio


目录结构如下图
在这里插入图片描述

新建客服端启动类 AioClient

public class AioClient {public static void main(String[] args) throws Exception {AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open();Future<Void> future = socketChannel.connect(new InetSocketAddress("192.168.108.89", 7397));System.out.println("com.lm.netty01.aio client start done. {码农明哥 | 欢迎关注&获取源码}");future.get();socketChannel.read(ByteBuffer.allocate(1024), null, new AioClientHandler(socketChannel, Charset.forName("GBK")));Thread.sleep(100000);}}

客户端消息处理器类

public class AioClientHandler extends ChannelAdapter {public AioClientHandler(AsynchronousSocketChannel channel, Charset charset) {super(channel, charset);}@Overridepublic void channelActive(ChannelHandler ctx) {try {System.out.println("程序员码农 | 链接报告信息:" + ctx.channel().getRemoteAddress());//通知客户端链接建立成功} catch (IOException e) {e.printStackTrace();}}@Overridepublic void channelInactive(ChannelHandler ctx) {}@Overridepublic void channelRead(ChannelHandler ctx, Object msg) {System.out.println("码农明哥 | 服务端收到:" + new Date() + " " + msg + "\r\n");ctx.writeAndFlush("客户端信息处理Success!\r\n");}
}

服务端

public class AioServer extends Thread {private AsynchronousServerSocketChannel serverSocketChannel;@Overridepublic void run() {try {serverSocketChannel = AsynchronousServerSocketChannel.open(AsynchronousChannelGroup.withCachedThreadPool(Executors.newCachedThreadPool(), 10));serverSocketChannel.bind(new InetSocketAddress(7397));System.out.println("com.lm.netty01 aio server start done.  欢迎关注&获取源码}");// 等待CountDownLatch latch = new CountDownLatch(1);serverSocketChannel.accept(this, new AioServerChannelInitializer());latch.await();} catch (Exception e) {e.printStackTrace();}}public AsynchronousServerSocketChannel serverSocketChannel() {return serverSocketChannel;}public static void main(String[] args) {new AioServer().start();}
}

初始化

public class AioServerChannelInitializer extends ChannelInitializer {@Overrideprotected void initChannel(AsynchronousSocketChannel channel) throws Exception {channel.read(ByteBuffer.allocate(1024), 10, TimeUnit.SECONDS, null, new AioServerHandler(channel, Charset.forName("GBK")));}
}

处理消息

public class AioServerHandler extends ChannelAdapter {public AioServerHandler(AsynchronousSocketChannel channel, Charset charset) {super(channel, charset);}@Overridepublic void channelActive(ChannelHandler ctx) {try {System.out.println("码农明哥| 链接报告信息:" + ctx.channel().getRemoteAddress());//通知客户端链接建立成功ctx.writeAndFlush("码农明哥 | 通知服务端链接建立成功" + " " + new Date() + " " + ctx.channel().getRemoteAddress() + "\r\n");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void channelInactive(ChannelHandler ctx) {}@Overridepublic void channelRead(ChannelHandler ctx, Object msg) {System.out.println("码农明哥 | 服务端收到:" + new Date() + " " + msg + "\r\n");ctx.writeAndFlush("服务端信息处理Success!\r\n");}
}

Channle适配器模仿Netty

public abstract class ChannelAdapter implements CompletionHandler<Integer, Object> {private AsynchronousSocketChannel channel;private Charset charset;public ChannelAdapter(AsynchronousSocketChannel channel, Charset charset) {this.channel = channel;this.charset = charset;if (channel.isOpen()) {channelActive(new ChannelHandler(channel, charset));}}@Overridepublic void completed(Integer result, Object attachment) {try {final ByteBuffer buffer = ByteBuffer.allocate(1024);final long timeout = 60 * 60L;channel.read(buffer, timeout, TimeUnit.SECONDS, null, new CompletionHandler<Integer, Object>() {@Overridepublic void completed(Integer result, Object attachment) {if (result == -1) {try {channelInactive(new ChannelHandler(channel, charset));channel.close();} catch (IOException e) {e.printStackTrace();}return;}buffer.flip();channelRead(new ChannelHandler(channel, charset), charset.decode(buffer));buffer.clear();channel.read(buffer, timeout, TimeUnit.SECONDS, null, this);}@Overridepublic void failed(Throwable exc, Object attachment) {exc.printStackTrace();}});} catch (Exception e) {e.printStackTrace();}}@Overridepublic void failed(Throwable exc, Object attachment) {exc.getStackTrace();}public abstract void channelActive(ChannelHandler ctx);public abstract void channelInactive(ChannelHandler ctx);// 读取消息抽象类public abstract void channelRead(ChannelHandler ctx, Object msg);}

服务端测试
启动服务端
在这里插入图片描述
在这里插入图片描述

BIO


目录结构如下
在这里插入图片描述

客户端


public class BioClient {public static void main(String[] args) {try {Socket socket = new Socket("192.168.2.178", 7397);System.out.println("itstack-demo-netty bio client start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}");BioClientHandler bioClientHandler = new BioClientHandler(socket, Charset.forName("utf-8"));bioClientHandler.start();} catch (IOException e) {e.printStackTrace();}}
}

消息处理器

public class BioClientHandler extends ChannelAdapter {public BioClientHandler(Socket socket, Charset charset) {super(socket, charset);}@Overridepublic void channelActive(ChannelHandler ctx) {System.out.println("链接报告LocalAddress:" + ctx.socket().getLocalAddress());ctx.writeAndFlush("hi! 我是码农明哥 BioClient to msg for you \r\n");}@Overridepublic void channelRead(ChannelHandler ctx, Object msg) {System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);ctx.writeAndFlush("hi 我已经收到你的消息Success!\r\n");}
}

服务端

public class BioServer extends Thread {private ServerSocket serverSocket = null;public static void main(String[] args) {BioServer bioServer = new BioServer();bioServer.start();}@Overridepublic void run() {try {serverSocket = new ServerSocket();serverSocket.bind(new InetSocketAddress(7397));System.out.println("com.lm.netty01.bio bio server start done. {关注码农明哥| 欢迎关注&获取源码}");while (true) {Socket socket = serverSocket.accept();BioServerHandler handler = new BioServerHandler(socket, Charset.forName("GBK"));handler.start();}} catch (IOException e) {e.printStackTrace();}}
}

消息处理器


public class BioServerHandler extends ChannelAdapter {public BioServerHandler(Socket socket, Charset charset) {super(socket, charset);}@Overridepublic void channelActive(ChannelHandler ctx) {System.out.println("链接报告LocalAddress:" + ctx.socket().getLocalAddress());ctx.writeAndFlush("hi! 我是码农明哥 BioServer to msg for you \r\n");}@Overridepublic void channelRead(ChannelHandler ctx, Object msg) {System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);ctx.writeAndFlush("hi 我已经收到你的消息Success!\r\n");}
}

适配器

public abstract class ChannelAdapter extends Thread {private Socket socket;private ChannelHandler channelHandler;private Charset charset;public ChannelAdapter(Socket socket, Charset charset) {this.socket = socket;this.charset = charset;while (!socket.isConnected()) {break;}channelHandler = new ChannelHandler(this.socket, charset);channelActive(channelHandler);}@Overridepublic void run() {try {BufferedReader input = new BufferedReader(new InputStreamReader(this.socket.getInputStream(), charset));String str = null;while ((str = input.readLine()) != null) {channelRead(channelHandler, str);}} catch (IOException e) {e.printStackTrace();}}// 链接通知抽象类public abstract void channelActive(ChannelHandler ctx);// 读取消息抽象类public abstract void channelRead(ChannelHandler ctx, Object msg);
}

BIO测试
启动服务端

在这里插入图片描述
在这里插入图片描述

NIO


目录结构如下
在这里插入图片描述
客户端

public class NioClient {public static void main(String[] args) throws IOException {Selector selector = Selector.open();SocketChannel socketChannel = SocketChannel.open();socketChannel.configureBlocking(false);boolean isConnect = socketChannel.connect(new InetSocketAddress("192.168.2.178", 7397));if (isConnect) {socketChannel.register(selector, SelectionKey.OP_READ);} else {socketChannel.register(selector, SelectionKey.OP_CONNECT);}System.out.println("com.lm.netty01.nio nio client start done. {关注码农明哥 | 欢迎关注&获取源码}");new NioClientHandler(selector, Charset.forName("GBK")).start();}
}

消息处理器

public class NioClientHandler  extends ChannelAdapter {public NioClientHandler(Selector selector, Charset charset) {super(selector, charset);}@Overridepublic void channelActive(ChannelHandler ctx) {try {System.out.println("链接报告LocalAddress:" + ctx.channel().getLocalAddress());ctx.writeAndFlush("hi! 我是,码农明哥 NioClient to msg for you \r\n");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void channelRead(ChannelHandler ctx, Object msg) {System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);ctx.writeAndFlush("hi 我已经收到你的消息Success!\r\n");}
}

服务端

public class NioServer {private Selector selector;private ServerSocketChannel socketChannel;public static void main(String[] args) throws IOException {new NioServer().bind(7893);}public void bind(int port) {try {selector = Selector.open();socketChannel = ServerSocketChannel.open();socketChannel.configureBlocking(false);socketChannel.socket().bind(new InetSocketAddress(port), 1024);socketChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("com.lm.netty01.nio server start done. {关注码农明哥 | 欢迎关注&获取源码}");new NioServerHandler(selector, Charset.forName("GBK")).start();} catch (IOException e) {e.printStackTrace();}}}

消息处理器

public class NioServerHandler extends ChannelAdapter {public NioServerHandler(Selector selector, Charset charset) {super(selector, charset);}@Overridepublic void channelActive(ChannelHandler ctx) {try {System.out.println("链接报告LocalAddress:" + ctx.channel().getLocalAddress());ctx.writeAndFlush("hi! 我是码农明哥 NioServer to msg for you \r\n");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void channelRead(ChannelHandler ctx, Object msg) {System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);ctx.writeAndFlush("hi 我已经收到你的消息Success!\r\n");}}

Nio测试
启动NioServer
在这里插入图片描述
在这里插入图片描述
好了到这里就结束了基础的netty学习,大家一定要跟着动手操作起来。需要的源码的 可私信我获取;
重要:
给大家构建了个资源群 欢迎圈友携朋友一起加入 大家需要的si我进。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/880802.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go基础学习06-Golang标准库container/list(双向链表)深入讲解;延迟初始化技术;Element;List;Ring

基础介绍 单向链表中的每个节点包含数据和指向下一个节点的指针。其特点是每个节点只知道下一个节点的位置&#xff0c;使得数据只能单向遍历。 示意图如下&#xff1a; 双向链表中的每个节点都包含指向前一个节点和后一个节点的指针。这使得在双向链表中可以从前向后或从后…

无人机之数据提取篇

一、无人机平台与传感器 无人机是进行数据采集的基础设施&#xff0c;其稳定性、可靠性、灵活性和负载能力直接影响到数据采集的效果。根据实际需求&#xff0c;需选择适合的无人机类型&#xff0c;如固定翼无人机适合大范围、长时间的数据采集&#xff0c;而多旋翼无人机则更适…

Redis 实现分布式锁时需要考虑的问题

引言 分布式系统中的多个节点经常需要对共享资源进行并发访问&#xff0c;若没有有效的协调机制&#xff0c;可能会导致数据竞争、资源冲突等问题。分布式锁应运而生&#xff0c;它是一种保证在分布式环境中多个节点可以安全地访问共享资源的机制。而在Redis中&#xff0c;使用…

HTML基础用法介绍一

VS code 如何快速生成HTML骨架注释是什么&#xff1f;为什么要写注释&#xff1f;注释的标签是什么&#xff1f;标题标签段落标签换行标签与水平线标签 (都是单标签&#xff09;文本格式化标签图片标签超链接标签音频标签视频标签 &#x1f698;正片开始 VS code 如何快速生成…

基于Spring框架的分层解耦详解

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;Java Web关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Java Web 三层架构&#xff1a; Java Web可以大致被分为三层架构&#xff1a;…

怎么在Vue3项目中引入Vant组件库并使用?

文章目录 前言一、项目中使用步骤1.安装&#xff1a;2.样式的导入&#xff08;2种方法&#xff09;2.1 main.ts全局导入&#xff08;平常自己的项目用的这个全局&#xff09;2.2 按需引入组件样式 (简单介绍一下)1.安装插件2.配置插件 3.组件按需使用&#xff1a;App.vue 总结 …

5QI(5G QoS Identifier)

5QI&#xff08;5G QoS Identifier&#xff0c;5G 服务质量标识符&#xff09;是在5G网络中用于定义特定数据流所需服务级别的指标。它用于优先处理流量&#xff0c;并根据流量的类型及其特定需求分配网络资源。5QI值从1到255&#xff0c;每个值对应一组QoS参数&#xff0c;这些…

数据结构和算法基础(一)

文章目录 链表反转链表合并删除链表倒数第 n 个结点找链表的中间结点链表中环的检测排序算法递归 趁空闲时间刷一遍极客时间上王争的《数据结构与算法之美》课程&#xff0c;个人觉得写的很好&#xff0c;每章节由浅入深且从基础到引入设计类问题&#xff0c;如果写过很多代码想…

成都睿明智科技有限公司抖音电商服务靠谱吗?

在这个电商风起云涌的时代&#xff0c;抖音作为短视频直播的超级流量池&#xff0c;正深刻改变着人们的购物习惯。无数商家蜂拥而至&#xff0c;渴望在这片蓝海中找到属于自己的岛屿。而提及抖音电商服务&#xff0c;成都睿明智科技有限公司无疑是一个备受瞩目的名字。那么&…

WebSocket 在 Spring Boot 中的高级应用指南

WebSocket 在 Spring Boot 中的高级应用指南 深入理解WebSocket协议 深入理解STOMP协议 1. 概述 WebSocket 是一种基于 TCP 的全双工通信协议&#xff0c;允许服务器和客户端之间进行持续的双向通信。与传统的 HTTP 请求-响应模型不同&#xff0c;WebSocket 是一个持久的连接…

Linux 进程的基本概念及描述

目录 0.前言 1. 什么是进程 1.1 进程的定义与特性 1.2 进程与线程的区别 2.描述进程 2.1 PCB (进程控制块) 2.2 task_struct 3.查看进程 3.1 查看进程信息 3.1.1 /proc 文件系统 3.1.2 ps 命令 3.1.2 top 和 htop 命令 3.2 获取进程标识符 3.2.1使用命令获取PID 3.2.2 使用C语言…

微信小程序数据操作指南:从绑定到更新

微信小程序数据操作指南&#xff1a;从绑定到更新 在微信小程序开发中&#xff0c;数据操作是核心环节之一。微信小程序提供了一系列简洁而强大的数据操作方法&#xff0c;帮助开发者轻松实现数据的绑定、更新和渲染。本文将详细介绍微信小程序中常用的数据操作方法&#xff0…

加密与安全_HTOP 一次性密码生成算法

文章目录 HOTP 的基础原理HOTP 的工作流程HOTP 的应用场景HOTP 的安全性安全性增强措施Code生成HOTP可配置项校验HOTP可拓展功能计数器&#xff08;counter&#xff09;计数器在客户端和服务端的作用计数器的同步机制客户端和服务端中的计数器表现服务端如何处理计数器不同步计…

AIGC学习笔记—minimind详解+训练+推理

前言 这个开源项目是带我的一个导师&#xff0c;推荐我看的&#xff0c;记录一下整个过程&#xff0c;总结一下收获。这个项目的slogan是“大道至简”&#xff0c;确实很简。作者说是这个项目为了帮助初学者快速入门大语言模型&#xff08;LLM&#xff09;&#xff0c;通过从零…

vue3学习记录-computed

vue3学习记录-computed 1.为什么要用computed2.使用方法2.1 基本实例2.2 可写计算属性 1.为什么要用computed 写个购物车的案例 <script setup> import { ref, reactive,computed } from "vue" const tableData reactive([{ name: 商品1, price: 10, num: 1…

3. 轴指令(omron 机器自动化控制器)——>MC_MoveRelative

机器自动化控制器——第三章 轴指令 5 MC_MoveRelative变量▶输入变量▶输出变量▶输入输出变量 功能说明▶指令详情▶时序图▶重启运动指令▶多重启动运动指令▶异常 MC_MoveRelative 指定自指令当前位置起的移动距离&#xff0c;进行定位。 指令名称FB/FUN图形表现ST表现MC…

初始C语言(五)

前言 本文章就代表C语言介绍以及了解正式完成&#xff0c;后续进行具体分析和详细解析学习。知识根深蒂固才可以应付后来的学习&#xff0c;地基要打好&#xff0c;后续才会轻松。 十四、结构体 结构体是C语言中最最重要的知识点&#xff0c;使得C语言有能力描述复杂的类型。 …

使用fastapi搭建ChatGPT对话后台

使用fastapi搭建ChatGPT对话后台 参考资料&#xff1a;使用fastapi搭建ChatGPT对话后台 效果&#xff1a;在本地构建网页达成类似chatgpt的对话效果&#xff0c;一个字一个字的返回生成结果 ChatGPT初步调用 import os import fastapi import dotenv from httpx import AsyncC…

JVM(HotSpot):字符串常量池(StringTable)

文章目录 一、内存结构图二、案例讲解三、总结 一、内存结构图 JDK1.6 JDK1.8 我们发现&#xff0c;StringTable移入了Heap里面。所以&#xff0c;应该想到&#xff0c;StringTable将受到GC管理。 其实&#xff0c;1.6中&#xff0c;在方法区中的时候&#xff0c;也是受GC管…

从底层理解为什么常量区中的代码不能被修改?

目录 前言&#xff1a;一、了解虚拟地址二、页表映射三、常量区不能被修改的原理四、常量区不可修改的意义 前言&#xff1a; 平时我们在编写代码时都会用到或遇到所谓的常量区或者不可修改的代码&#xff0c;比如说用双引号包起来字符串&#xff08;“Hello World”&#xff…