0

I'm currently working on a little Client/Server task with using sockets. Sadly I the client hangs when it is supposed to read the "200 OK File Created" sent by the server. Is there anything i overlooked?

Client:

public HTTPClient(InetAddress adress, int portnumber, String filename) throws IOException {
    socket = new Socket(adress, portnumber);
    input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    output = new PrintWriter(socket.getOutputStream());
    this.filename = filename;
}

public void sendPutRequest() throws IOException {
    output.println("PUT /" + filename + " HTTP/1.0");
    output.flush();
    File myFile = new File(this.filename);
    if (myFile.exists()) {
        for (String string : Files.readAllLines(myFile.toPath())) {
            output.println(string);
        }
        output.flush();
        String line;
        while ((line = input.readLine()) != null) {
            System.out.println(line);
        }
    } else {
        throw new IOException("File not found");
    }
}

Server:

  try (Socket client = this.socket.accept(); 
    BufferedReader in = new BufferedReader(
    new InputStreamReader(client.getInputStream()));
    PrintWriter out = new PrintWriter(client.getOutputStream())) {

    String lineIn = in.readLine();
    if (lineIn.contains("PUT")) {
        String filename = lineIn.split(" ")[1].substring(1);
        List<String> filedata = new ArrayList<>();
        String line;
        while ((line = in.readLine()) != null) {
            filedata.add(line);
            System.out.println(line);
        }
        writeToFile(filename, filedata);
        out.println("200 OK File Created");
        out.flush();
    }
}
Shinobu
  • 11
  • 7

2 Answers2

1

Your server is reading from the connection until it is closed (only in such a case in.readLine()will return null).

However your client does not close the connection to the server. Therefore the server is stuck in the while loop.

Solution: You have to close the output stream after sending the request. Alternatively detect the end of the request on server side without waiting for the "end of stream" limit.

Robert
  • 39,162
  • 17
  • 99
  • 152
  • Note: Usually with HTTP the `Content-Length:` header will show how long the body is and where it ends. see: http://stackoverflow.com/questions/15991173/is-the-content-length-header-required-for-a-http-1-0-response for details. – ebyrob Mar 31 '16 at 18:27
  • If i would close the connection rightaway, I wouldn't be able to send the client an acknowledge afterwards or am I misunderstanding something? – Shinobu Mar 31 '16 at 18:36
  • Nevermind i got i now. I transfered the number of lines before doing any reading on the server side. Thank you for your help. – Shinobu Mar 31 '16 at 18:55
  • @ebyrob: We are talking about the code reading the request, not the response. AFAIR in HTTP the request end is indicated by two empty lines. – Robert Apr 01 '16 at 07:53
0

In your server code:

            while ((line = in.readLine()) != null) {
                filedata.add(line);
                System.out.println(line);
            }
             writeToFile(filename, filedata); // getting to this line?

Your server is never getting to the writeToFile line, because the socket connection is still open, and it's still in the while loop. As a solution, use DataFetcher

ControlAltDel
  • 33,923
  • 10
  • 53
  • 80