详细谈谈AIO、BIO、NIO 的区别

news2024/10/6 10:36:08

目录

一、什么是AIO

二、什么是BIO

三、什么是NIO

四、NIO 在 Netty 中的使用


一、什么是AIO

AIO(Asynchronous I/O,异步输入输出)是一种处理输入输出的编程模型,它允许同时处理多个输入输出操作,而不需要等待每个操作完成。在Python中,可以使用asyncio库来实现AIO编程。

下面是一个使用asyncio库简单示例代码:

import asyncio
​
async def hello():
    print("Hello")
    await asyncio.sleep(1)
    print("World")
​
async def main():
    await asyncio.gather(hello(), hello())
​
asyncio.run(main())

在这个示例中,hello函数是一个异步函数,它打印"",然后等待1秒钟,最后再打印"World"。main函数是另一个异步函数,它使用asyncio.gather方法同时运行两个hello任务。

通过asyncio.run(main())来运行main函数,它会创建一个事件循环并执行异任务。

运行上述代码,你会看到输出结果是交替打印的"Hello"和"World",而不是等待一个任务完成后再执行另一个任务。这就是AIO的特点,可以同时处理多个任务,提高程序的效率。

二、什么是BIO

BIO(BlockI/O,阻塞输入输出)是一种传统的输入输出模型,它在执行输入输出操作时会阻塞程序的执行,直到操作完成才会进行下一步。在Java中,可以使用java.net包中的SocketServerSocket类来实现BIO编程。下面是一个简单的Java示例代码:

Server端代码:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
​
public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("Server started.");
​
            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("Client connected.");
​
                InputStream inputStream = socket.getInputStream();
                OutputStream outputStream = socket.getOutputStream();
​
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) != -1) {
                    String message = new String(buffer, 0, length);
                    System.out.println("Received message: " + message);
​
                    outputStream.write(message.getBytes());
                    outputStream.flush();
                }
​
                socket.close();
                System.out.println("Client disconnected.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Client端代码:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
​
public class Client {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("localhost", 8888);
            System.out.println("Connected to server.");
​
            InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream();
​
            String message = "Hello, server!";
            outputStream.write(message.getBytes());
            outputStream.flush();
​
            byte[] buffer = new byte[1024];
            int length = inputStream.read(buffer);
            String response = new String(buffer, 0, length);
            System.out.println("Received response: " + response);
​
            socket.close();
            System.out.println("Disconnected from server.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,Server端通过ServerSocket监听8888端口,当有Client连接时,会创建一个新的Socket来与Client进行通信。Server端使用InputStream来接收Client发送的消息,然后通过OutputStream发送响应消息给Client。Client端通过Socket连接到Server,并使用InputStream发送消息给Server,然后通过OutputStream接收Server的响应消息。

需要注意的是,BIO模型中的输入输出操作是阻塞的,也就是说当没有数据可读取或写入时,程序会一直阻塞在相应的读取或写入操作处,直到有数据或者操作完成才会继续执行。

 

三、什么是NIO

NIO(New IO)是Java中用于处理非阻塞I/O操作的API,它提供了一种更高效、更灵活的方式来进行网络编程。

下面是一个简单的Java NIO示例代码,展示了如何使用NIO进行文件复制操作:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
​
public class NIOFileCopyExample {
    public static void main(String[] args) {
        String sourceFilePath = "path/to/source/file";
        String destinationFilePath = "path/to/destination/file";
​
        try {
            // 创建输入流和流
            FileInputStream fis = new FileInputStream(sourceFilePath);
            FileOutputStream fos = new FileOutputStream(destinationFilePath);
​
            // 创建输入流和输出流的通道
            FileChannel inputChannel = fis.getChannel();
            FileChannel outputChannel = fos.getChannel();
​
            // 创建缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(1024);
​
            // 从输入通道取数据到缓冲区
            while (inputChannel.read(buffer) != -1) {
                buffer.flip(); // 切换为读模式
                // 从缓冲区写入数据到输出通道
                outputChannel.write(buffer);
                buffer.clear(); // 清空缓冲区
            }
​
            // 关闭通道和流
 inputChannel.close();
            outputChannel.close();
            fis.close();
            fos.close();
​
            System.out.println("文件复制完成!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

以上代码通过使用NIO的FileChannelByteBuffer,实现了从源文件复制数据到目标文件操作。需要注意的是,该示例中只是简单地进行文件复制,并未处理异常情况和完善错误处理。在实际应用中,可能需要进一步优化和处理相关逻辑。

 

四、NIO 在 Netty 中的使用

在Netty中,NIO被广泛用于构建高性能的网络应用程序。Netty封装了Java NIO API,并提供了一套更简洁、易用的抽象层,使得开发者能够更方便地使用NIO进行网络编程。

下面是一个简单的Netty使用NIO的示例代码,展示了如何创建一个简单的Echo服务器:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
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;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
​
public class EchoServer {
    private int port;
​
    public EchoServer(int port) {
        this.port = port;
    }
​
    public void start() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .option(ChannelOption.SO_BACKLOG, 128)
             .handler(new LoggingHandler(LogLevel.INFO))
             .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new StringEncoder(), new StringDecoder(), new EchoServerHandler());
                }
             });
            
            // 绑定端口,开始接收进来的连接
            b.bind(port).sync().channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
​
    public static void main(String[] args) throws Exception {
        int port = 8888;
        new EchoServer(port).start();
    }
}
​
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
​
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        String message = (String) msg;
        System.out.println("Received message: " + message);
        ctx.write(message);
    }
​
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }
​
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

以上代码创建了一个简单的Echo服务器,当客户端连接到服务器并发送消息时,服务器将原样将消息返回给客户端。在该示例中,NioEventLoopGroup用于处理I/O事件的多线程事件循环组,NioServerSocketChannel用于创建服务器端的通道,ChannelOption.SO_BACKLOG设置了服务器的最大连接数,LoggingHandler用于记录日志。EchoServerHandler类继承自ChannelInboundHandlerAdapter,用于处理接收到的消息。

这只是一个简单的示例,你可以根据实际需求,使用Netty的NIO功能进行更复杂的网络应用程序开发。

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

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

相关文章

Activity的自启动模式

以下内容摘自郭霖《第一行代码》第三版 文章目录 Activity的自启动模式1.standard&#xff08;默认&#xff09;2.singleTop3.singleTask4.singleInstance Activity的自启动模式 启动模式一共有4种&#xff0c;分别是standard、singleTop、singleTask和singleInstance&#x…

java: MultiValueMap

实际就是value为List的map.在较早版本(比如2.3.7)的spring boot 的loadSpringFacotories方法中有使用&#xff0c; 新版本(比如2.6.6&#xff09;已换成Map<String,List> MultiValueMap用法很简单&#xff1a;

资产盘点流程及注意事项

公司在引进固定资产管理的同时&#xff0c;也广泛加快了信息化工作的进程。现代计算机技术、条码技术、条码技术等都不能满足传统的固资管理机制&#xff0c;RFID技术、硬件扫描技术、提高固定资产管理流程、固定资产管理和统计等方面的特殊要求。科学规范地管控企业有形资产的…

日常环境配置

pip install 使用代理 例&#xff1a;代理端口&#xff1a;10808 pip install akshare --proxyhttp://127.0.0.1:10808———— conda 虚拟环境安装pip包 查看虚拟环境地址 conda info --env #查看虚拟环境地址使用–taget 安装pip 包 pip install akshare --target &q…

DataSphere Studio - 1.1.0安装部署 (单机版)

不要采用这种安装方式&#xff01;&#xff01;全部服务启动成功&#xff0c;不报错。页面还是各种报错&#xff0c;效率非常低下。 感谢微信群各位大佬帮助&#xff0c;分享了社区优秀文章中一键自动化部署脚本。 喝咖啡&#xff0c;自动部署&#xff0c;课本上故事成真。 自…

ChatGLM-6B模型使用

一、创建环境 conda create -n chatglm python3.8 conda activate chatglm 二、下载代码 git clone https://github.com/THUDM/ChatGLM-6B.git三、安装依赖 我这里是cuda11.2&#xff0c;根据自己的版本安装&#xff0c;这里是pytorch版本&#xff1a;https://pytorch.org/g…

linux系统编程重点复习--文件和目录操作

目录 复习目标 1.文件IO 2.C标准函数与系统函数的区别 2.1什么是系统调用 2.2 文件描述符 2.3 open函数 2.4 close函数 2.5 read/write 2.5.1read函数 2.5.2 write 2.6 lseek 2.7 perror和errno 2.8 阻塞和非阻塞: 3文件和目录 3.1 stat/lstat函数 3.2 opendir…

在使用Python爬虫时遇到解析错误解决办法汇总

在进行Python爬虫任务时&#xff0c;遇到解析错误是常见的问题之一。解析错误可能是由于网页结构变化、编码问题、XPath选择器错误等原因导致的。为了帮助您解决这个问题&#xff0c;本文将提供一些实用的解决办法&#xff0c;并给出相关的代码示例&#xff0c;希望对您的爬虫任…

【好书推荐】ChatGPT入门经典《这就是 ChatGPT》

文章目录 一、前言二、通俗易懂三、传奇大佬四、精彩的导读序五、总结 一、前言 目前很少能有一本书&#xff0c;能做到一定深度地普及 ChatGPT 的原理&#xff0c;而这本书可以做到恰到好处地告诉大家&#xff0c;ChatGPT 是如何工作的。 二、通俗易懂 ChatGPT 是一种人工智…

PCB制版技术

1、在头脑里形成一个原理图----现在就下载AD9盖版&#xff0c;诞生了一个问题&#xff0c;电路板去哪里买&#xff0c;买了怎么焊接电路和芯片&#xff0c;怎样流程化批量制作电子产品 1.1 形成一个PCB板&#xff0c;形成一个结构 1.2 焊接&#xff0c;嫁接&#xff0c;组装等 …

低功耗LCD液晶显示驱动厂家1621系列3线/4线接口可驱动32×4COM

型 号&#xff1a;VK1621 / 品 牌&#xff1a;VINKA/永嘉微电 最新年份 M1817 VK1621 是一个324的LCD驱动器&#xff0c;可软体程式控制使其适用于多样化的LCD应用线路&#xff0c;仅用到3至4条信号线便可控制LCD驱动器&#xff0c;除此之外也可介由指令使其進入省电模式 VK1…

Acwing.873.欧拉函数

题目 给定n个正整数ai&#xff0c;请你求出每个数的欧拉函数。 输入格式 第一行包含整数n。 接下来n行&#xff0c;每行包含一个正整数ai。 输出格式 输出共n行&#xff0c;每行输出一个正整数an的欧拉函数。 数据范围 1 ≤n ≤100 1≤ai≤2* 109 输入样例: 3 3 6 8输…

面试官:如何跟非技术人员解释黑盒、白盒、灰盒测试的区别?

​对于黑盒、白盒与灰盒测试方法的理解&#xff0c;几年前我在某乎做过一个概念性的回答&#xff0c;当时提问者询问&#xff1a;如何跟非技术人员解释黑盒、白盒、灰盒测试的区别&#xff1f; 我的回答原文如下&#xff1a; 既然是对非技术人员解释&#xff0c;就不能用专业…

绘制Circos基因圈图

写在前面 昨天在绘制Circos圈图&#xff0c;已经隔了2年左右没有做这类的图了。这时间过得真是快&#xff0c;但是文章和成果依旧是没有很明显的成效。只能安慰自己&#xff0c;后面的时间继续加油吧&#xff01;关于Cirocs图的制作&#xff0c;我从刚开始到现在都是是使用TBt…

PCB制版技术02

4.30 PCB库很重视它实际的尺寸和样子 4.31 PCB库很重视它实际的尺寸和样子&#xff0c;但是原理图就不需要了&#xff0c;我们只是在原理上做一个解释 4.32 我们习惯把角放在中央的位置 4.43 鼠标的右键可以取消选择的方框 4.44 放置引脚&#xff0c;连续击两下就出来了 4.45 …

从声通科技的发展来看,AI行业如何回答可持续盈利这一命题?

AI浪潮下&#xff0c;相关企业头顶新兴技术的光环&#xff0c;脚下是亏损的阴影。尽管业内不同企业身处不同的细分赛道&#xff0c;但是在巨大的成本支出面前&#xff0c;步伐还是有些难迈开。 当前&#xff0c;也有一些AI企业希望借助风口在更受投资者关注的舞台施展拳脚。据…

你真的会自动化吗?Web自动化测试-PO模式实战,一文通透...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 PO模式 Page Obj…

2.数组,对象,元组,自定义类型,接口,字面量,枚举,any

目录 1 数组 2 对象 3 元组 4 类型别名(自定义类型) 5 接口 5.1 基本使用 5.2 接口继承 6 字面量类型 7 枚举类型 7.1 基本使用 7.2 枚举的默认值 7.3 给枚举数值 7.4 给枚举字符串值 7.5 ts的枚举转换为js 8 any类型 1 数组 只包含数字的数组…

联想存储 HH0301_DE4000H

Help - Eclipse SDKhttps://thinksystem.lenovofiles.com/storage/help/index.jsp?topic%2Fthinksystem_system_manager_11.60.3%2Foverview.html&langzh/CN池和卷组的工作原理 要配置存储、可创建池或卷组&#xff0c;用于容纳要在存储阵列中使用的硬盘&#xff08;HDD&…

复习之linux系统的引导修复

启动Linux系统时&#xff0c;需要先通电&#xff0c;接着系统会自动进行bios初始化&#xff0c;对硬件进行检测并初始化硬件时钟&#xff0c;之后就进入了 Linux系统引导过程。Linux系统引导过程的具体内容和引导修复方法将在下文中进行详细介绍。由于我们在引导修复时需要利用…