Пытаясь ускорить чтение из сокета в Java - PullRequest
2 голосов
/ 21 июня 2011

Я пытаюсь создать клиент, который может отправлять HTTP-запросы и получать ответы от веб-серверов.Я пытался использовать класс Java HttpURLConnection, но он не дает мне достаточного контроля над тем, что фактически отправляется на сервер, поэтому я хотел бы составить свои собственные сообщения HTTP-запроса и отправить их через сокет.Тем не менее, чтение из InputStream Socket является чрезмерно медленным для некоторых серверов, и я хотел бы ускорить это, если это возможно.Вот некоторый код, который я использовал для проверки того, насколько медленными были чтения для сокета по сравнению с HttpURLConnection:

public static void useURLConnection() throws Exception
{
    URL url = new URL("http://" + hostName + "/");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    InputStream in = conn.getInputStream();
    byte[] buffer = new byte[buffersize];
    long start = System.currentTimeMillis();
    while(in.read(buffer) != -1) { }
    System.out.println(System.currentTimeMillis() - start);
}

public static void useSocket() throws Exception
{
    byte[] request = ("GET / HTTP/1.1\r\nHost: " + hostName + "\r\n\r\n").getBytes();
    Socket socket = new Socket(hostName, 80);
    OutputStream out = socket.getOutputStream();
    InputStream in = socket.getInputStream();
    out.write(request);
    byte[] buffer = new byte[buffersize];
    long start = System.currentTimeMillis();
    while(in.read(buffer) != -1) { }
    System.out.println(System.currentTimeMillis() - start);
}

Оба метода выполняются примерно одинаково для некоторых серверов, например, www.wikipedia.org, но чтение из сокета намного медленнее - минуты, а не миллисекунды - для других, таких как www.google.com.Может кто-нибудь объяснить, почему это так, и, возможно, дать мне несколько советов о том, что, если что-нибудь, я могу сделать, чтобы ускорить чтение из сокета?Спасибо.

1 Ответ

4 голосов
/ 21 июня 2011

Итак, HTTP / 1.1 по умолчанию включает keepalive для клиентских запросов.В вашем примере с сокетом вы отправляете HTTP / 1.1 в качестве строки версии, поэтому вы неявно принимаете, что можете поддерживать keepalive, но при этом полностью игнорируете его.

По сути, вы блокируете попыткичтобы прочитать больше с сервера, несмотря на тот факт, что сервер ждет, чтобы вы что-то предприняли (либо отправьте другой запрос, либо закройте соединение.)

Вам нужно либо отправить заголовок «Соединение: закрыть», либоотправьте HTTP / 1.0 в качестве строки версии.

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