【从NIO到Netty】8.零拷贝案例2-网络传输

这个例子,在客户端通过transferTo方法,直接将文件通过DMA拷贝到socketChannel,服务端将收到的数据进行打印到控制台

客户端

package org.scaventz.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 NewIoClient {
    public static void main(String[] args) throws IOException {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("localhost", 7001));
        String filename = "d:/test.txt";

        // 得到一个文件的channel
        FileChannel fileChannel = new FileInputStream(filename).getChannel();

        // 准备发送
        long startTime = System.currentTimeMillis();

        // 在linux下一个transferTo方法就可以完成传输
        // 在windows下一次调用transferTo只能发送8M文件,就需要分段传输文件,而且要注意传输时的位置
        // transferTo底层使用到了零拷贝
        long transferCount = fileChannel.transferTo(0, 8 * 1024 * 1024, socketChannel);

        System.out.println("发送的总的字节数 = " + transferCount + " 耗时 = " + (System.currentTimeMillis() - startTime));
        fileChannel.close();
    }
}

服务端

package org.scaventz.zerocopy;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/**
 * @Description
 */
public class NewIoServer {
    public static void main(String[] args) throws IOException {
        InetSocketAddress address = new InetSocketAddress(7001);
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        ServerSocket serverSocket = serverSocketChannel.socket();
        serverSocket.bind(address);

        // 创建buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
        while (true) {
            SocketChannel socketChannel = serverSocketChannel.accept();
            int count = 0;
            while (count != -1) {
                try {
                    // 将数据读入 byteBuffer
                    count = socketChannel.read(byteBuffer);
                    System.out.println(new String(byteBuffer.array()));
                } catch (Exception e) {
                    e.printStackTrace();
                    break;
                }
                byteBuffer.rewind(); // 倒带 position = 0, mark=-1 作废
            }
        }
    }
}
原文地址:https://www.cnblogs.com/heben/p/13203784.html