Рекомендуемый способ чтения из сокета на HTTP-сервере - PullRequest
4 голосов
/ 03 марта 2012

В качестве задачи я реализовал базовый веб-сервер на Java.Когда я открываю raw InputStream, я немедленно захожу в блокирующее чтение, которое считывает все 400 или байты HTTP-запроса в байтовый массив.Это работает, однако я не проверяю больше данных и просто закрываю сокет после отправки ответа.

Мне интересно, есть ли более надежный способ сделать это, чтобы не пропустить какие-либо данные изклиент.Я думал о чтении одного байта за раз, пока read не вернул конец потока.Однако вместо этого иногда блокируется, когда данных больше нет, и в JavaDocs для public abtract int InputStream.read() говорится:

If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

Таким образом, это означает, что две вещи могут произойти, если конец потокаДостигнут: возврат -1 и блокировка.Я вижу блокировку.

Мой вопрос, с протоколом, таким как HTTP, как вы должны читать из сокета и как вы узнаете, когда это все данные, которые вы будете получать в этом соединении?

1 Ответ

7 голосов
/ 03 марта 2012

Указанный вами JavaDoc не подразумевает, что две вещи могут произойти, если достигнут конец потока. Он не говорит блоки чтения , когда обнаружен конец потока, но до , когда обнаружен конец потока. Как только он обнаружен, возвращается -1.

Это объясняет поведение, которое вы наблюдаете: конец потока не обнаружен, и чтение заблокировано. Конец потока обнаруживается после закрытия соединения, но не закрывается, так как клиент не закрывает соединение сразу после отправки запроса. Он должен быть открыт для получения ответа.

Чтобы убедиться, что вы получаете все данные от клиента, вы должны анализировать их HTTP-запрос, пока не увидите конец заголовка (двойной перевод строки) плюс любой объем данных, указанный в заголовке (если есть).

Если вы хотите избежать блокировки, взгляните на java.nio и каналы (SocketChannel в частности).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...