Я пытаюсь прочитать HTTP-запрос от Bufferedreader, который получает Socket.getInputStream() в качестве входных данных. Однако, когда я использую Bufferedreader.lines().foreach(), он никогда не завершается и просто застревает.

Мой код (упрощенно):

Socket socket = new ServerSocket(9090);
Socket newConnection = socket.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(newConnection.getInputStream()));
reader.lines().forEach(s -> System.out.println(s));
0
Fedor Finkenflugel 2 Апр 2014 в 12:42
3
Я подозреваю, что это блокирует ожидание данных из сокета, который никогда не придет.
 – 
McDowell
2 Апр 2014 в 12:45

2 ответа

Лучший ответ

Вам необходимо узнать больше о протоколе HTTP 1.1. Запросы не завершаются концом потока. Они завершаются исчерпанием счетчика байтов в заголовке Content-length или кумулятивных фрагментов, если используется режим фрагментированной передачи. Если они будут исчерпаны к концу потока, вы никогда не сможете отправить ответ.

4
user207421 2 Апр 2014 в 12:56
1
+1 Хороший ответ. Я пропустил ссылку на HTTP, когда впервые прочитал вопрос.
 – 
Duncan Jones
2 Апр 2014 в 12:57
1
Запросы не обязательно имеют Content-length. Может просто иметь пустой контент. Поскольку код из вопроса, кажется, читает запрос header, стоит отметить, что заголовок заканчивается первой пустой строкой. И этот HTTP/1.1 позволяет отправлять несколько запросов через одно соединение.
 – 
Holger
2 Апр 2014 в 14:46
«Если бы они были исчерпаны к концу потока, вы никогда не смогли бы отправить ответ». Не совсем верно. Http-соединение проходит через TCP-соединение, TCP-соединение может быть наполовину разорвано, когда одна сторона отправляет FIN, а другая сторона подтверждает FIN, но все еще отправляет данные. В java это можно сделать с помощью Socket.shutdownOutput. Вы, вероятно, путаете с обычным закрытием сокета, которое закрывает оба сразу
 – 
Ferrybig
3 Мар 2016 в 18:40

Попробуйте создать свой сокет с конструктором без параметров и используйте connect () с параметром порта и тайм-аута. Это предотвратит бесконечное замораживание.

-2
Kojotak 2 Апр 2014 в 12:49
2
Код OP находится на стороне сервера, а не на стороне клиента соединения.
 – 
T.J. Crowder
2 Апр 2014 в 12:51