• 【从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 作废
                }
            }
        }
    }
  • 相关阅读:
    码农如何通过编程赚更多的钱
    理解 OAuth 2.0 认证流程
    把同事的代码重写得干净又整洁,老板却让我做回滚?
    精读《如何做好 CodeReview》
    互联网行业的软件与人员的代际更迭随想
    十大最佳自动化测试工具
    使用 docker 高效部署你的前端应用
    在Linux 命令行中转换大小写
    Python批量检测服务器端口可用性与Socket函数使用
    基于华为云CSE微服务接口兼容常见问题
  • 原文地址:https://www.cnblogs.com/heben/p/13203784.html
Copyright © 2020-2023  润新知