【问题标题】:Java NIO loops on socketChannel.read()socketChannel.read() 上的 Java NIO 循环
【发布时间】:2018-02-01 17:39:21
【问题描述】:

我试图了解错误在哪里但没有成功。 该场景是连接到接收文件的服务器的客户端,一种“上传”。服务器然后打开一个 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 守卫中的 read() 总是读取 1024 个字节(这个值来自调试)。

有什么想法吗?

【问题讨论】:

  • 您是否尝试在buffer.flip() 之后使用buffer.compact()?我承认我没有仔细阅读您的代码...

标签: java nio socketchannel


【解决方案1】:

这个复制循环的正确写法如下:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 2014-01-10
    • 1970-01-01
    • 2012-05-20
    相关资源
    最近更新 更多