c_o_d_e_
c_o_d_e_
2021-01-23 23:00

Java NIO中发送文件,客户端的缓冲区大小为什么会影响服务端接收文件的完整性?

  • java
  • linux
  • 缓存

客户端的关键代码如下

            File sendfile = new File(filepath+filename);
            FileChannel fileChannel = new FileInputStream(sendfile).getChannel();
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress(serverAddress,serverPort));
            socketChannel.configureBlocking(false);

          
            while(!socketChannel.finishConnect()){
                //自旋
            }


            //主要是这里的问题,我在windows系统的本地测试完全没问题
            //但是在云服务器上(linux)测试就有问题,我的图片文件大小约为为84kb
            //当客户端这里的缓冲区大小设为1024时,服务端接收到的文件就只有64kb
            //当客户端这里的缓冲区大小设为10240时,服务端接收到的文件就只有70kb
            //当客户端这里的缓冲区大小设为102400时,服务端接收到的文件才是完整的84kb
            ByteBuffer filebuffer = ByteBuffer.allocate(1024);

            int len = 0;
            while((len = fileChannel.read(filebuffer)) != -1){
                filebuffer.flip();
                socketChannel.write(filebuffer);
                filebuffer.clear();
            }

            //读完文件通道关闭
            fileChannel.close();
            socketChannel.close();

服务端的关键代码如下

    private void receiveFile(SelectionKey key){
        //服务端一直是1024没变过,我试过修改也没影响        
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        FileData fileData = map.get(key.channel());

        SocketChannel socketChannel = (SocketChannel) key.channel();
        String path= System.getProperty("user.dir")+"\\resource\\server\\test.jpg";
        long start = System.currentTimeMillis();
        try {
            int len = 0;
            while ((len = socketChannel.read(buffer)) != -1) {
                buffer.flip();
                File file = new File(path);
                if(!file.exists()) file.createNewFile();

                FileChannel fileChannel = new FileOutputStream(file).getChannel();
                fileChannel.write(buffer) 
                buffer.clear();//清除本次缓存区内容
            }
        fileChannel .close();
        key.cancel();
    }

主要问题就在客户端设置ByteBuffer的大小那里,我在windows系统的本地测试完全没问题
但是在云服务器上(linux)测试就有问题,我的图片文件大小约为为84kb
当客户端这里的缓冲区大小设为1024时,服务端接收到的文件就只有64kb
当客户端这里的缓冲区大小设为10240时,服务端接收到的文件就只有70kb
当客户端这里的缓冲区大小设为102400时,服务端接收到的文件才是完整的84kb

所以不明白为什么会出现这种linux服务器和windows本地测试的差异性?这种情况是如何发生的?

  • 点赞
  • 回答
  • 收藏
  • 复制链接分享

0条回答