1

I'm trying to understand where is the error without success. The scenario is a client that connects to a server that receive a file, a sort of "upload". The server then open a FileChannel, reads all the data and store it in a buffer that is copied into the local file.

SERVER

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();
            }
        }
    }

CLIENT

 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");

The client terminates is flow since it print File sent. Instead the server does not exit from the LOOP1. I don't understand why the read() in loop1 guard always reads 1024 bytes (this value came from debugging) even if the client has closed the channel (in fact it terminated all the flow).

Any idea?

alessandro308
  • 1,912
  • 2
  • 15
  • 27
  • Did you try to use `buffer.compact()` after `buffer.flip()`? I admit I didn't read your code too carefully... – zlakad Feb 01 '18 at 09:36

1 Answers1

1

The correct way to write this copy loop is as follows:

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

If the side reading from the socket channel never exits from this loop, the peer hasn't closed the connection.

user207421
  • 305,947
  • 44
  • 307
  • 483