【Netty】NIO 缓冲区 ( Buffer ) 分散 Scattering 与 聚合 Gathering 操作
文章目錄
- I . 緩沖區 ( Buffer ) 分散 Scattering 與 聚合 Gathering 概念
- II . 緩沖區 ( Buffer ) 分散 Scattering 與 聚合 Gathering 示例 ( 客戶端 )
- III . 緩沖區 ( Buffer ) 分散 Scattering 與 聚合 Gathering 示例 ( 服務器端 )
I . 緩沖區 ( Buffer ) 分散 Scattering 與 聚合 Gathering 概念
1 . 分散 Scattering 對應緩沖區寫入 : 通道 ( Channel ) 向 緩沖區數組 中寫出數據 , 按照索引從第 0 個緩沖區 ( Buffer ) 開始, 依次寫入數據 ;
緩沖區 ( Buffer ) 分散 ( Scattering ) 對應方法 : 這是一類方法 , 有很多 , 這里只舉一個例子說明 ;
public long read(ByteBuffer[] dsts) throws IOException;2 . 聚合 Gathering 對應緩沖區讀取 : 通道 ( Channel ) 從 緩沖區數組 中讀取數據 , 按照索引從第 0 個緩沖區 ( Buffer ) 開始, 依次讀取數據 ;
緩沖區 ( Buffer ) 聚合 ( Gathering ) 對應方法 : 這是一類方法 , 有很多 , 這里只舉一個例子說明 ;
public long write(ByteBuffer[] srcs) throws IOException;分散 Scattering 與 聚合 Gathering 都是 通道 ( Channel ) 對 緩沖區數組 ( Buffer[] ) 進行讀寫的操作 ;
II . 緩沖區 ( Buffer ) 分散 Scattering 與 聚合 Gathering 示例 ( 客戶端 )
客戶端需求 : 本節演示代碼的重心在服務器端 , 服務器端演示 分散 聚合 的具體操作 , 客戶端只是演示 網絡套接字 流程 , 這里客戶端使用 BIO , 使用 TCP 協議進行簡單的數據發送 ;
package kim.hsl.bio;import java.io.IOException; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.Socket;public class TCPClient {public static void main(String[] args) {try {Socket socket = new Socket();InetSocketAddress inetSocketAddress =new InetSocketAddress(Inet4Address.getLocalHost(), //本機IP地址8888 //端口號);System.out.println("客戶端開始連接 ...");//此處會阻塞等待連接成功socket.connect(inetSocketAddress);System.out.println("客戶端連接成功");//連接成功后, 開始執行后續操作socket.getOutputStream().write("Hello World".getBytes());System.out.println("客戶端寫出 Hello World 成功");} catch (IOException e) {e.printStackTrace();}} }
這是之前的示例中使用過的 , 這里在用一次 , 實現的功能 就是 連接目標 IP 地址的 8888 端口 , 發送 “Hello World” 字符串給服務器 , 之后退出 ;
III . 緩沖區 ( Buffer ) 分散 Scattering 與 聚合 Gathering 示例 ( 服務器端 )
1 . 示例需求 : 服務器端使用多個 緩沖區 ( Buffer ) 組成的數組 , 進行讀寫數據 , 客戶端上傳的數據 通過 套接字通道 ( SocketChannel ) 寫出到 緩沖區數組中 , 服務器端再使用 文件通道 ( FileChannel ) 將數據寫出到本地文件中 ;
2 . 示例分析 :
① 緩沖區數組 : ByteBuffer[] buffers = new ByteBuffer[2]; , 創建一個緩沖區數組 , 將這兩個緩沖區數組作為讀寫操作的載體 , 讀取數據時就涉及到了緩沖區的 聚合 操作 , 寫出數據時 , 就涉及到了 分散 操作 ;
② 分散 Scattering : socketChannel.read(buffers); , 這里直接將數據讀取存放到了 緩沖區數組中 , 是將數據分散放入緩沖區數組 , 涉及到 緩沖區 分散 操作 ;
③ 聚合 Gathering : fcOut.write(buffers); , 這里將兩個緩沖區的數據 寫出到了文件中 , 將分散的數據輸入到一個文件中 , 涉及到 緩沖區 聚合 操作 ;
④ 注意緩沖區翻轉操作 : 先讀取數據 , 之后必須調用 flip() 方法翻轉緩沖區 , 然后再寫出數據 , 否則會出錯 ;
3 . 示例代碼 :
package kim.hsl.nio;import java.io.FileOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel;/*** 分散 ( Scattering ) 與 聚合 ( Gathering ) 示例** 分散 ( Scattering ) : 通道 ( Channel ) 向 緩沖區數組 中寫出數據,* 按照索引從第 0 個緩沖區 ( Buffer ) 開始, 依次寫入數據* 聚合 ( Gathering ) : 通道 ( Channel ) 從 緩沖區數組 中讀取數據,* 按照索引從第 0 個緩沖區 ( Buffer ) 開始, 依次讀取數據** 使用 服務器套接字通道 ( ServerSocketChannel ) 和 套接字通道 ( SocketChannel ) 進行聚合演示* 使用 文件通道 ( FileChannel ) 進行分散演示** @author han**/ public class BufferDemo4 {public static void main(String[] args) {try {//1 . 創建 ServerSocketChannel, 綁定本地端口ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();InetSocketAddress inetSocketAddress = new InetSocketAddress(8888);serverSocketChannel.socket().bind(inetSocketAddress);//2 . 創建 2 個 ByteBuffer, 并放入數組中ByteBuffer[] buffers = new ByteBuffer[2];buffers[0] = ByteBuffer.allocate(4);buffers[1] = ByteBuffer.allocate(8);//3 . ServerSocketChannel 阻塞等待客戶端連接, 該方法執行后一直阻塞SocketChannel socketChannel = serverSocketChannel.accept();//4 . 阻塞讀取數據, 將數據讀取到 buffers 緩沖區數組中的緩沖區中socketChannel.read(buffers);//5 . 將兩個 緩沖區 flip 翻轉一下, position 設置為 0buffers[0].flip();buffers[1].flip();//6 . 將讀取到的數據寫出到文件中FileOutputStream fos = null;try {//1 . FileChannel 可以從 FileOutputStream 中獲取fos = new FileOutputStream("file4.txt");//2 . 創建 FileChannel , 從 FileInputStream / FileOutputStream 中可以獲取到//FileChannel 是抽象類 , 實際類型是 FileChannelImplFileChannel fcOut = fos.getChannel();//3 . 將讀取到的數據寫出到文件中fcOut.write(buffers);} catch (IOException e) {e.printStackTrace();} finally {try {if(fos != null)fos.close();} catch (IOException e) {e.printStackTrace();}}} catch (IOException e) {e.printStackTrace();}} }
4 . 執行 服務器端 與 客戶端 程序 : 一定要按照順序執行 , 先啟動服務器端 , 再啟動客戶端 ;
① 啟動服務器端 : 先運行服務器端 ;
② 啟動客戶端 : 再運行客戶端 ;
客戶端開始連接 ... 客戶端連接成功 客戶端寫出 Hello World 成功③ 查看服務器端文件寫出結果 :
總結
以上是生活随笔為你收集整理的【Netty】NIO 缓冲区 ( Buffer ) 分散 Scattering 与 聚合 Gathering 操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Netty】NIO 缓冲区 ( Buf
- 下一篇: 【Netty】NIO 选择器 ( Sel