【Netty】零拷贝案例 ( transferTo | transferFrom )(二)

简介: 【Netty】零拷贝案例 ( transferTo | transferFrom )(二)

三、 零拷贝案例 服务器端


1 . 阻塞模式 与 非阻塞模式 :



① 非阻塞模式 : 如果调用 服务器套接字通道 ( ServerSocketChannel ) 的 configureBlocking(false) 方法设置非阻塞模式 , 就需要使用 Selector 注册通道 , 并监听事件 ;


② 阻塞模式 : 如果不经过上述设置 , 只需要使用如下方式 , 调用 accept() 方法阻塞等待客户端连接 , 如下用法 ; 这是 服务器套接字通道 ( ServerSocketChannel ) 的阻塞模式的使用 , 这里只是为了演示零拷贝机制 , 代码从简 ;



2 . 零拷贝操作 : 将 Socket 缓冲区中的数据直接拷贝到 内核缓冲区中 , 然后写出到文件 ;


使用零拷贝机制 , 一行代码完成 20M 的文件从 Socket 接收到硬盘文件写出操作 ;


fileChannel.transferFrom(socketChannel, 0, 1024 * 1024 * 32);


3 . 代码示例 :


package kim.hsl.nio.zerocopy;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class NIOFileServerDemo {
    public static void main(String[] args) {
        try {
            // 1. 创建并配置 服务器套接字通道 ServerSocketChannel
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.socket().bind(new InetSocketAddress(8888));
            // 注意这里使用阻塞模式, 不调用该代码
            //serverSocketChannel.configureBlocking(false);
            // 2. 获取文件通道
            FileChannel fileChannel = new FileOutputStream("book2.pdf").getChannel();
            // 3. 阻塞等待
            SocketChannel socketChannel = serverSocketChannel.accept();
            // 4. 零拷贝核心操作
            fileChannel.transferFrom(socketChannel, 0, 1024 * 1024 * 32);
            // 5. 释放资源
            //socketChannel.close();
            //fileChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}







四、 零拷贝案例 客户端


1 . 零拷贝操作 : 调用 transferTo 方法 , 可以直接将硬盘中的文件传输到服务器端 ;


该方法传输速度快的原理就是使用了零拷贝的机制 , 从文件系统直接拷贝到目标通道 ;


fileChannel.transferTo(totalCount, 1024 * 1024 * 32, socketChannel)



2 . 代码示例 :


package kim.hsl.nio.zerocopy;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
public class NIOFileClientDemo {
    public static void main(String[] args) {
        try {
            // 1. 创建并配置 服务器套接字通道 ServerSocketChannel
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress("127.0.0.1", 8888));
            //socketChannel.configureBlocking(false);
            // 2. 从文件输入流中获取文件通道 ( FileChannel )
            FileChannel fileChannel = new FileInputStream("book.pdf").getChannel();
            long startTime = System.currentTimeMillis();
            // 3. 零拷贝传输数据, 注意记录每次拷贝的起始位置
            long transferLen;
            long totalCount = 0;
            // 使用零拷贝将文件数据传到服务器, 循环终止条件是传输结果小于等于 0
            while ( ( transferLen = fileChannel.transferTo(totalCount, 1024 * 1024 * 32, socketChannel) ) > 0 ) {
                totalCount += transferLen;
            }
            System.out.println("文件传输完毕, 用时 : " + (System.currentTimeMillis() - startTime) + " ms");
            // 4. 关闭连接
            socketChannel.close();
            fileChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}






五、 零拷贝案例 运行与分析


1 . 运行代码 :



① 首先运行服务器程序 : 启动即可 ;


② 再运行客户端程序 : 此时会记录整体的运行事件 , 此时从客户端向服务器端传输 20M 文件用时 68ms ;


image.png



2 . NIO 零拷贝 与 BIO 传统拷贝对比 :



BIO 传统拷贝 从客户端向服务器端传输 20MB 文件需要 229 ms ;


NIO 的零拷贝 从客户端向服务器端传输 20MB 文件需要 68ms ;



显然 NIO 零拷贝 传输效率有极大的提升 ;


目录
相关文章
|
4月前
|
前端开发 网络协议 Java
Netty | 工作流程图分析 & 核心组件说明 & 代码案例实践
Netty | 工作流程图分析 & 核心组件说明 & 代码案例实践
115 0
|
8月前
|
网络协议
由浅入深Netty聊天室案例
由浅入深Netty聊天室案例
33 0
|
8月前
|
消息中间件 分布式计算 NoSQL
由浅入深Netty入门案例
由浅入深Netty入门案例
98 0
|
9月前
|
存储
前中电技术总监带你了解,什么是零拷贝,Netty是如何实现的?
呢作为一个高性能的网络通信框架,被越来越多互联网公司关注和重视。最近,有小伙伴在面试过程中被问到Netty是如何实现零拷贝的问题?,今天,我给大家来聊一聊。另外,往期面试题解析中配套的文档我已经准备好,想获得的可以在我的煮叶简介中找到。
38 0
|
10月前
Netty入门到超神系列-聊天室案例
对于服务端而言需要做如下事情 selector监听客户端的链接 如果有“读”事件,就从通道读取数据 把数据转发给其他所有的客户端,要过滤掉发消息过来的客户端不用转发 对于客户端而言需要做如下事情 selector监听服务端的“读”事件 如果有数据从通道中读取数据,打印到控制台 监听键盘输入,向服务端发送消息
86 0
|
10月前
|
存储 消息中间件 缓存
Netty入门到超神系列-零拷贝技术
内存主要作用是在计算机运行时为操作系统和各种程序提供临时储存,操作系统的进程和进程之间是共享CPU和内存资源的。为了防止内存泄露需要一套完善且高效的内存管理机制。因此现代操作系提供了一种基于主内存抽象出来的概念:虚拟内存(Virtual Memory)。 虚拟内存 虚拟内存是计算机系统内存管理的一种技术,主要为每个进程提供私有的地址空间,让每个进程拥有一片连续完整的内存空间。而实际上,虚拟内存通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换,加载到物理内存中来 物理内存 物理内存指通过内存条而获得的内存空间,而虚拟内存则是指将硬盘的一块区域划分来
99 0
|
10月前
|
Java
Netty入门到超神系列-Java NIO零拷贝实战
这一章我们来操作一下NIO的零拷贝,这里我会先写代码样式一下传统IO数据拷贝场景下的耗时,然后再对比NIO场景下的考别耗时,通过耗时差异就能看到NIO零拷贝和传统IO拷贝的区别了。
82 0
|
10月前
|
存储 Java Linux
Netty ByteBuf 的零拷贝(Zero Copy)详解
Netty ByteBuf 的零拷贝(Zero Copy)详解
126 0
|
12月前
Netty - 探究零拷贝Zero Copy
Netty - 探究零拷贝Zero Copy
35 0
|
12月前
|
Rust Dubbo 网络协议
通过 HTTP/2 协议案例学习 Java & Netty 性能调优:工具、技巧与方法论
通过 HTTP/2 协议案例学习 Java & Netty 性能调优:工具、技巧与方法论
12564 3