2017-02-20 5 views
0

Я пытаюсь построить HTTP-сервер, используя сокеты, но у меня возникла странная проблема. Кажется, все работает нормально, но когда я использую свой браузер для получения html-файла или txt-файла, я не получаю последний символ.HTTP-сервер, не отправляющий последний символ в потоке вывода

Например, у меня довольно стандартный тестовый файл .html. Этот файл заканчивается точно после </html>, поэтому браузер получает весь файл, но заканчивается </html.

С изображениями они выглядят поврежденными, но я полагал, что это связано с предыдущей проблемой.

Код следующее:

printWriter.println(
     this.getStatusLineFromStatusCode(statusCode) + CRLF 
     + "Date: " + currentTime + CRLF 
     + "Server: Definitely not Apache" + CRLF 
     + ((statusCode == 200) ? 
       "Last-Modified: " + lastModified + CRLF : "") 
     + "Content-Length: " + dir.length() + CRLF 
     + "Content-Type: " + fileType + CRLF + CRLF 
    ); 

if(request.get("requestMethod").equals("GET") 
     && dir.exists() && dir.isFile()) { 
    FileInputStream in = null; 

    try { 
     System.out.println(dir.getPath()); 
     in = new FileInputStream(dir.getPath()); 
     int c; 
     while((c = in.read()) != -1) { 
      outputStream.write(c); // Here is the write operation 
     } 


    } catch(Exception e) { 
     System.out.println(e); 
    } finally { 
     if(in != null) { 
      in.close(); 
     } 
    } 
} 

printWriter.close(); 

я заметил ту часть, где происходит от записи. Это действительно странно, потому что если я использую FileOutputStream для копирования в одно и то же время файла в другое место на моем диске, файл копируется правильно.

Кто-нибудь знает, почему это происходит?

+0

эту помощь? http://stackoverflow.com/a/51753/7491770 – ram

+0

@ram К сожалению, я не могу использовать 'IOUtils' – Flerex

+0

Промыть выходной поток, прежде чем вы его закроете. –

ответ

3

Проблема в том, что вы печатаете CRLF + CRLF, но также и печать с println, которая добавляет еще одну новую строку. Эта дополнительная новая строка считается частью содержимого, и поскольку заголовок длины содержимого предопределен, последний символ фактического содержимого отбрасывается.

Вскоре, используйте print, а не println в следующей части:

printWriter.println(
    this.getStatusLineFromStatusCode(statusCode) + CRLF 
    + "Date: " + currentTime + CRLF 
    + "Server: Definitely not Apache" + CRLF 
    + ((statusCode == 200) ? 
      "Last-Modified: " + lastModified + CRLF : "") 
    + "Content-Length: " + dir.length() + CRLF 
    + "Content-Type: " + fileType + CRLF + CRLF 
); 
МАЕ
+0

Ничего себе. Хорошо поймал! Я никогда этого не увижу. Если я удаляю последний '+ CRLF', все работает, но если я изменю' println' на 'print', я получаю HTML-код как текст, а затем, также как текст, HTTP-запрос. http://i.imgur.com/aKbAyLF.png Почему это? – Flerex

+0

После печати промойте автора. Хотя он создан с включенной функцией автозапуска, он может быть очищен только после новых строк, т. Е. Вызовов println. – ram

+0

Если вы предпочитаете удалять дополнительные CRLF, у вас могут возникнуть проблемы, если сервер является linux, поскольку println будет объявлять только LF, а не CRLF. Поэтому предпочитайте использовать печать с двойным CRLF. – ram

Смежные вопросы