Java HTTP / 1.1 GET-запрос BufferedReader readLine никогда не останавливается - PullRequest
0 голосов
/ 14 марта 2020

Здравствуйте, я делаю HTTP-клиент. Я пытаюсь получить код Google's html. У меня есть проблема, функция BufferedReader.readLine () блокируется бесконечно, потому что удаленный сервер, очевидно, не отправляет пустую строку? Или может быть, что мой запрос неверен?

Ценю любую помощь!

public static void main(String[] args) {
        String uri = "www.google.com";
        int port = 80;
        Socket socket = new Socket(uri, port);
        PrintWriter toServer = new PrintWriter(socket.getOutputStream(), true);
        InputStream inputStream = socket.getInputStream();
        get(uri, port, language, socket, toServer, inputStream);
}

public static void get(String uri, int port, String language, Socket socket, PrintWriter toServer, InputStream inputStream) {
        try {
            toServer.println("GET / HTTP/1.1");
            toServer.println("Host: " + uri + ":" + port);
            toServer.println();

            // Parse header
            StringBuilder stringBuilder = new StringBuilder();

            BufferedReader fromServer = new BufferedReader(new InputStreamReader(inputStream));

            String line;
                while ((line = fromServer.readLine()) != null) {
                    stringBuilder.append(line);
                }
            System.out.println("done");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

1 Ответ

3 голосов
/ 14 марта 2020

Вы отправляете запрос HTTP / 1.1, который по умолчанию включает поддержку активности HTTP. Это означает, что сервер может оставить TCP-соединение открытым после отправки ответа, чтобы принимать больше запросов от клиента. Вместо этого ваш код предполагает, что сервер закроет соединение после завершения ответа, явно ожидая, что readline вернет null. Но так как сервер не закроет соединение (или только после некоторого длительного времени ожидания), readline просто заблокируется.

Чтобы исправить это, используйте вместо этого HTTP / 1.0 (по умолчанию keep-alive отключен) HTTP / 1.1 или явно указать серверу, что больше запросов не будет отправлено, добавив заголовок Connection: close.

Обратите внимание, что в целом HTTP намного сложнее, чем вы думаете, если вы только что видели несколько примеров. Проблема, с которой вы сталкиваетесь в своем вопросе, - это лишь проблеск в другие проблемы, с которыми вы столкнетесь, продолжая этот путь. Если вы действительно хотите реализовать свою собственную обработку HTTP вместо использования установленных библиотек, изучите действующий стандарт, а не просто предполагайте конкретное c поведение.

...