0

I have a client and server program that is supposed to work like this:

  • Client types in a filename into the command line (stdin) and the server sends the client the file data through the socket.
  • Client types in another name and another file are sent.

However, I am currently only able to get one file to be sent. The second time I type in a filename, it does not go into the while loop in my Client here:

while ((count = in.read(buffer)) > 0) {

Client (variable "fromUser" is the filename of the requested file from the server, outCommands is the outgoing datastream that transmits this filename to the Server):

while (true) {
    fromUser = stdIn.readLine();
    if (fromUser != null) {
        outCommands.println(fromUser);

        while ((count = in.read(buffer)) > 0) {
            String fileName = "downloaded" + in.readUTF();
            OutputStream fileOut = new FileOutputStream(fileName);

            try {
                fileOut.write(buffer, 0, count);
                fileOut.flush();
            } catch (IOException e) {
            }
            fileOut.close();
            break;
        }
    } else if (fromUser.equals("Stop")) {
        in.close();
        stdIn.close();
        dlSocket.close();
    }
}

Server ("dlp" is the server socket, "out" is the outgoing datastream):

while (!(fileD = in.readLine()).equals(null)) {
    System.out.println("Line read:" + fileD);

    // Load file
    File file = new File(fileD);
    System.out.println(file.getAbsolutePath());

    System.out.println("File created...");
    InputStream fileIn = new FileInputStream(file);

    outputLine = dlp.processInput(null);

    byte[] buffer = new byte[8192];
    int count;
    while ((count = fileIn.read(buffer)) > 0) {
        System.out.println("Beginning file transfer");
        out.write(buffer, 0, count);
    }

    System.out.println("Completed file transfer");
    // Write filename to out socket
    out.writeUTF(file.getName());
    out.writeLong(file.length());
    out.flush();
}

in.close();
out.close();
clientSocket.close();

Can someone help me figure out why this is happening? I don't understand why count = in.read(buffer) is not greater than zero once the server sends over the second file after it's requested by the client.

Src: https://github.com/richardrl/downloader/tree/master/src/main/java

Zain Aftab
  • 703
  • 7
  • 21
user3180
  • 1,369
  • 1
  • 21
  • 38
  • break is not a problem http://stackoverflow.com/questions/12393231/break-statement-inside-two-while-loops – Sanjit Kumar Mishra May 17 '16 at 14:13
  • There are numerous problems with this code, starting with the assumption that an entire file is read in exactly one read, and extending to writing the length and never reading it, and writing the filename and the length after the file instead of before, which is when they are both needed. See my answer in the duplicate. – user207421 May 18 '16 at 03:46
  • Specifically, `count = in.read(buffer)` can never be non-zero once it has reached end of stream after the first file. That's why you need to know the length before the file is sent, so you know how many bytes to read. This code will throw `EOFException` on the second `readUTF()`. – user207421 May 18 '16 at 05:43
  • Thank you @EJP ! It is working now after I make the changes in your above post. Except why did my original code assume it's "read in exactly one read"? In the code you linked, does the "close()" close the write process for one file to move onto the next one? – user3180 May 18 '16 at 09:43

1 Answers1

2

Because you used break in the while loop it breaks and does not go back to the loop condition. Instead of break you should use continue - or even better, remove it as it is unnecessary at the end of a loop's scope (about to re-iterate anyway):

while ((count = in.read(buffer)) > 0) {
    String fileName = "downloaded" + in.readUTF();
    OutputStream fileOut = new FileOutputStream(fileName);
    try {
        fileOut.write(buffer, 0, count);
        fileOut.flush();
    } catch (IOException e) {

    }
    fileOut.close();
    // continue; // not needed
}

When executing the line with continue the loop stops and the next line to execute is the loop condition. As said, this isn't required here since you're about to re-iterate anyway.

Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88
Gal Dreiman
  • 3,969
  • 2
  • 21
  • 40