日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2025/6/17 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Netty】零拷贝案例 ( transferTo | transferFrom ) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一、 案例需求
  • 二、 傳統(tǒng) BIO 拷貝案例
  • 三、 零拷貝案例 服務(wù)器端
  • 四、 零拷貝案例 客戶端
  • 五、 零拷貝案例 運行與分析





一、 案例需求



給出兩個案例 , 一個是 使用普通的 BIO 模型 傳輸文件的案例 , 一個是 NIO + 零拷貝 傳輸文件案例 ;

傳輸 20M 的文件 , 對比二者的傳輸效率 ;





二、 傳統(tǒng) BIO 拷貝案例



服務(wù)器端使用 ServerSocket , 客戶端使用 Socket , 在客戶端將文件傳輸給服務(wù)器端 , 并統(tǒng)計整體的時間消耗 ;


1 . 服務(wù)器端代碼 : 服務(wù)器端程序啟動后 , 監(jiān)聽 8888 端口 , 等待客戶端連接 , 客戶端連接成功后 , 讀取客戶端上傳的數(shù)據(jù) , 服務(wù)器端將接收到的數(shù)據(jù)存儲在 book2.pdf 文件中 ;

package kim.hsl.nio.zerocopy;import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket;public class BIOFileServerDemo {public static void main(String[] args) {try {// 1. 創(chuàng)建服務(wù)器套接字, 并等待客戶端連接ServerSocket serverSocket = new ServerSocket(8888);System.out.println("服務(wù)器啟動,監(jiān)聽 8888 端口");//阻塞, 等待客戶端連接請求 ( 此處是第一個阻塞點 )Socket socket = serverSocket.accept();long startTime = System.currentTimeMillis();System.out.println("客戶端連接成功");// 2. 接收客戶端傳輸?shù)臄?shù)據(jù), 并寫出到文件中InputStream inputStream = socket.getInputStream();FileOutputStream fileOutputStream = new FileOutputStream("book2.pdf");byte[] buffer = new byte[4096];int readLen;// 讀取的字節(jié)個數(shù)大于等于 0 才寫出數(shù)據(jù)while ( ( readLen = inputStream.read(buffer) ) >= 0 ) {// 寫出數(shù)據(jù)到服務(wù)器fileOutputStream.write(buffer, 0, readLen);}System.out.println("文件傳輸完畢, 用時 : " + (System.currentTimeMillis() - startTime) + " ms");// 3. 關(guān)閉流socket.close();inputStream.close();fileOutputStream.close();} catch (IOException e) {e.printStackTrace();}} }

2 . 客戶端代碼 : 客戶端連接本地的 8888 端口服務(wù)器 , 讀取本地的 book.pdf 文件 , 將其傳輸?shù)椒?wù)器中 ;

package kim.hsl.nio.zerocopy;import java.io.FileInputStream; import java.io.IOException; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.Socket;public class BIOFileClientDemo {public static void main(String[] args) {try {// 1. 客戶端連接服務(wù)器Socket socket = new Socket();InetSocketAddress inetSocketAddress =new InetSocketAddress(Inet4Address.getLocalHost(), 8888);socket.connect(inetSocketAddress);System.out.println("客戶端連接服務(wù)器成功, 開始傳輸文件 ...");long startTime = System.currentTimeMillis();// 2. 從文件中讀取數(shù)據(jù)數(shù)據(jù)并傳給服務(wù)器FileInputStream fileInputStream = new FileInputStream("book.pdf");byte[] buffer = new byte[4096];int readLen;// 讀取的字節(jié)個數(shù)大于等于 0 才寫出數(shù)據(jù)while ( ( readLen = fileInputStream.read(buffer) ) >= 0 ) {// 寫出數(shù)據(jù)到服務(wù)器socket.getOutputStream().write(buffer, 0, readLen);}System.out.println("文件傳輸完畢, 用時 : " + (System.currentTimeMillis() - startTime) + " ms");//3. 關(guān)閉連接socket.close();fileInputStream.close();} catch (IOException e) {e.printStackTrace();}} }

3 . 代碼運行 :


① 開啟服務(wù)器 : 服務(wù)器開啟后阻塞監(jiān)聽 ;


② 開啟客戶端 : 客戶端開啟 , 連接服務(wù)器 , 連接成功后 , 將 20M 的文件傳輸給服務(wù)器 ; 客戶端用時 229 ms 將數(shù)據(jù)傳輸給服務(wù)器 , 服務(wù)器用時 229 ms 接收并存儲數(shù)據(jù) , 二者時間基本差不多 ;






三、 零拷貝案例 服務(wù)器端



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


① 非阻塞模式 : 如果調(diào)用 服務(wù)器套接字通道 ( ServerSocketChannel ) 的 configureBlocking(false) 方法設(shè)置非阻塞模式 , 就需要使用 Selector 注冊通道 , 并監(jiān)聽事件 ;

② 阻塞模式 : 如果不經(jīng)過上述設(shè)置 , 只需要使用如下方式 , 調(diào)用 accept() 方法阻塞等待客戶端連接 , 如下用法 ; 這是 服務(wù)器套接字通道 ( ServerSocketChannel ) 的阻塞模式的使用 , 這里只是為了演示零拷貝機(jī)制 , 代碼從簡 ;


2 . 零拷貝操作 : 將 Socket 緩沖區(qū)中的數(shù)據(jù)直接拷貝到 內(nèi)核緩沖區(qū)中 , 然后寫出到文件 ;

使用零拷貝機(jī)制 , 一行代碼完成 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. 創(chuàng)建并配置 服務(wù)器套接字通道 ServerSocketChannelServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8888));// 注意這里使用阻塞模式, 不調(diào)用該代碼//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 . 零拷貝操作 : 調(diào)用 transferTo 方法 , 可以直接將硬盤中的文件傳輸?shù)椒?wù)器端 ;

該方法傳輸速度快的原理就是使用了零拷貝的機(jī)制 , 從文件系統(tǒng)直接拷貝到目標(biāo)通道 ;

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. 創(chuàng)建并配置 服務(wù)器套接字通道 ServerSocketChannelSocketChannel 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. 零拷貝傳輸數(shù)據(jù), 注意記錄每次拷貝的起始位置long transferLen;long totalCount = 0;// 使用零拷貝將文件數(shù)據(jù)傳到服務(wù)器, 循環(huán)終止條件是傳輸結(jié)果小于等于 0while ( ( transferLen = fileChannel.transferTo(totalCount, 1024 * 1024 * 32, socketChannel) ) > 0 ) {totalCount += transferLen;}System.out.println("文件傳輸完畢, 用時 : " + (System.currentTimeMillis() - startTime) + " ms");// 4. 關(guān)閉連接socketChannel.close();fileChannel.close();} catch (IOException e) {e.printStackTrace();}} }



五、 零拷貝案例 運行與分析



1 . 運行代碼 :


① 首先運行服務(wù)器程序 : 啟動即可 ;

② 再運行客戶端程序 : 此時會記錄整體的運行事件 , 此時從客戶端向服務(wù)器端傳輸 20M 文件用時 68ms ;


2 . NIO 零拷貝 與 BIO 傳統(tǒng)拷貝對比 :


BIO 傳統(tǒng)拷貝 從客戶端向服務(wù)器端傳輸 20MB 文件需要 229 ms ;

NIO 的零拷貝 從客戶端向服務(wù)器端傳輸 20MB 文件需要 68ms ;


顯然 NIO 零拷貝 傳輸效率有極大的提升 ;

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的【Netty】零拷贝案例 ( transferTo | transferFrom )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。