Java NIO 循环在 socketChannel.read() 上



我试图了解错误在哪里但没有成功。该方案是一个客户端,它连接到接收文件的服务器,这是一种"上传"。然后,服务器打开 FileChannel,读取所有数据并将其存储在复制到本地文件中的缓冲区中。

服务器

ServerSocketChannel ssf = ...//[Initialized into the costrutor]
    SocketChannel clientf = null;
    Path path = Paths.get(new File("").getAbsolutePath()+"/"+"example.txt");
    try {
        // Creating file to write
        FileChannel file = FileChannel.open(path, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE));
        clientf = ssf.accept();
        System.out.println("Client is connected");
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        int i=0;
        //Here I'll read the data sent from the client
        while (clientf.read(buffer) > 0) { //LOOP1
            buffer.flip();
            while (buffer.hasRemaining()) { //LOOP2
                file.write(buffer);
            }
            buffer.clear();
            i++; // Used in order to know how many iteration are performed
        }
        file.close();
        System.out.println("File received");
    } catch(IOException e){
            e.printStackTrace();
    }
    finally {
            // CLose all the open connections
        if(ssf != null) {
            try {
                if(clientf != null)
                    clientf.close();
                ssf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

客户

 byte[] message = new byte[x];
            in.readFully(message, 0, message.length);
            try {
                SocketChannel sockfile = SocketChannel.open();
                //sockfile.configureBlocking(false); //If this line is executed the client doesn't connect. Why?
                sockfile.connect(new InetSocketAddress(ip, portfile));
                File f = new File("");
                f = new File(f.getAbsoluteFile()+"/"+file);
                RandomAccessFile af = new RandomAccessFile(f,"r");
                FileChannel inCh = af.getChannel();
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                while (inCh.read(buffer) > 0) {
                    buffer.flip();
                    while(buffer.hasRemaining()) {
                        sockfile.write(buffer);
                    }
                    buffer.clear();
                }
                af.close();
            } catch (ParseException e) {
                e.printStackTrace();
            }
            System.out.println("File sent");

客户端终止是流,因为它打印File sent。相反,服务器不会退出 LOOP1。我不明白为什么 loop1 guard 中的 read(( 总是读取 1024 字节(此值来自调试(,即使客户端已关闭通道(实际上它终止了所有流(。

知道吗?

编写此复制循环的正确方法如下:

while (in.read(buffer) >= 0 || buffer.position() > 0)
{
    buffer.flip();
    out.write(buffer);
    buffer.compact();
}

如果从套接字通道读取的端从未退出此循环,则对等方尚未关闭连接。

最新更新