Можете ли вы объяснить процесс подключения HttpURLConnection?



я использую HTTPURLConnection для подключения к веб-службе. Я знаю, как использовать HTTPURLConnection но я хочу понять, как это работает. В принципе, я хочу знать следующее:




  • на какой момент делает HTTPURLConnection попробуйте установить соединение с данным URL?

  • на каком этапе я могу знать, что мне удалось успешно установить соединение?

  • устанавливают соединение и отправляют фактический запрос, выполненный за один шаг/вызов метода? Что такое метод это?

  • можете ли вы объяснить функцию getOutputStream и getInputStream в терминах непрофессионала? Я замечаю, что когда сервер, к которому я пытаюсь подключиться, не работает, я получаю Exception at getOutputStream. Значит ли это, что HTTPURLConnection будет только начать устанавливать соединение, когда я вызываю getOutputStream? Как насчет getInputStream? Так как я могу получить ответ только на getInputStream, то это значит, что я не посылал никаких запросов на getOutputStream но просто устанавливает соединение? Делай HttpURLConnection вернуться на сервер запрос ответа при вызове getInputStream?

  • правильно ли я говорю, что openConnection просто создает новый объект соединения, но еще не устанавливает никакого соединения?

  • как я могу измерить читаемые накладные расходы и подключить накладные расходы?

569   4  

4 ответов:

String message = URLEncoder.encode("my message", "UTF-8");

try {
    // instantiate the URL object with the target URL of the resource to
    // request
    URL url = new URL("http://www.example.com/comment");

    // instantiate the HttpURLConnection with the URL object - A new
    // connection is opened every time by calling the openConnection
    // method of the protocol handler for this URL.
    // 1. This is the point where the connection is opened.
    HttpURLConnection connection = (HttpURLConnection) url
            .openConnection();
    // set connection output to true
    connection.setDoOutput(true);
    // instead of a GET, we're going to send using method="POST"
    connection.setRequestMethod("POST");

    // instantiate OutputStreamWriter using the output stream, returned
    // from getOutputStream, that writes to this connection.
    // 2. This is the point where you'll know if the connection was
    // successfully established. If an I/O error occurs while creating
    // the output stream, you'll see an IOException.
    OutputStreamWriter writer = new OutputStreamWriter(
            connection.getOutputStream());

    // write data to the connection. This is data that you are sending
    // to the server
    // 3. No. Sending the data is conducted here. We established the
    // connection with getOutputStream
    writer.write("message=" + message);

    // Closes this output stream and releases any system resources
    // associated with this stream. At this point, we've sent all the
    // data. Only the outputStream is closed at this point, not the
    // actual connection
    writer.close();
    // if there is a response code AND that response code is 200 OK, do
    // stuff in the first if block
    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
        // OK

        // otherwise, if any other status code is returned, or no status
        // code is returned, do stuff in the else block
    } else {
        // Server returned HTTP error code.
    }
} catch (MalformedURLException e) {
    // ...
} catch (IOException e) {
    // ...
}

первые 3 ответа на ваши вопросы перечислены в виде встроенных комментариев, рядом с каждым методом, в Примере HTTP POST выше.

С getOutputStream:

возвращает выходной поток, который записывает в это соединение.

в принципе, я думаю, что у вас есть хорошее понимание того, как это работает, поэтому позвольте мне просто повторить, с точки зрения непрофессионала. getOutputStream в основном открывает подключение поток, с целью записи данных на сервер. В приведенном выше примере кода "сообщение" может быть комментарием, который мы отправляем на сервер, представляющий комментарий, оставленный на записи. Когда вы видите getOutputStream, ты открываешь подключение поток для записи, но вы на самом деле не пишете никаких данных, пока не позвоните writer.write("message=" + message);.

С getInputStream():

возвращает входной поток, который читает из этого соединения. Один SocketTimeoutException может быть вызвано при чтении из возвращенного входного потока, если тайм-аут чтения истекает до того, как данные будут доступны для чтения.

getInputStream совсем наоборот. Как getOutputStream, это подключение поток, но целью является чтение данных с сервера, а не запись на него. Если соединение или открытие потока не удается, вы увидите SocketTimeoutException.

как насчет getInputStream? Так как я могу только получить ответ на getInputStream, значит ли это, что я еще не отправил запрос на getOutputStream, а просто установил соединение?

имейте в виду, что отправка запроса и передачи данных-это две разные операции. Когда вы вызываете getOutputStream и getInputStreamurl.openConnection(), вы отправляете запрос на сервер для установления соединения. Существует рукопожатие, которое происходит, когда сервер отправляет вам подтверждение того, что соединение установленный. Именно в этот момент времени вы готовы отправлять или получать данные. Таким образом, вам не нужно вызывать getOutputStream в установить подключение откройте поток, если ваша цель для создания запроса не является отправка данных.

в терминах непрофессионала, делая getInputStream запрос-эквивалент телефонного звонка в дом вашего друга, чтобы сказать: "Эй, это нормально, если я приду и возьму пара вице-ручки?- и твой друг устанавливает рукопожатие со словами: "Конечно! Приходите и получите его". Затем, в этот момент, связь установлена, вы идете к дому своего друга, стучите в дверь, просите тиски и возвращаетесь в свой дом.

используя аналогичный пример для getOutputStream вы бы позвонили своему другу и сказали:"Эй, у меня есть деньги, которые я вам должен, могу ли я отправить их вам"? Ваш друг, нуждающийся в деньгах и больной внутри, что вы так долго держали его, говорит:"Конечно, давай над тобой дешевый ублюдок". Так что вы идете к своему дом друга и" Почта " деньги к нему. Затем он выгоняет вас, и вы идете обратно в свой дом.

теперь, продолжая пример непрофессионала, давайте рассмотрим некоторые исключения. Если вы позвонили своему другу и его не было дома, это может быть 500 ошибка. Если вы позвонили и получили сообщение с отключенным номером, потому что ваш друг устал от того, что вы все время занимаете деньги, это страница 404 не найдена. Если ваш телефон мертв, потому что вы не оплатили счет, это может быть исключение IOException. (Примечание: этот раздел может быть не на 100% правильным. Он призван дать вам общее представление о том, что происходит в условиях непрофессионала.)

Вопрос № 5:

Да, вы правы, что openConnection просто создает новый объект подключения, но не устанавливает его. Подключение будет установлено, когда вы вызова getInputStream и getOutputStream.

openConnection создает новый объект Connection. От URL.документации, содержащие вредоносные элементы:

новое соединение открывается каждый раз при вызове метода openConnection обработчика протокола для этого URL.

подключение будет установлено, когда вы называете содержащие вредоносные элементы, и InputStream, OutputStream, или как называется, когда вы их тиражируете.

Вопрос № 6:

чтобы измерить накладные расходы, я обычно обертываю некоторые очень простые сроки код вокруг всего блока подключения, например, так:

long start = System.currentTimeMillis();
log.info("Time so far = " + new Long(System.currentTimeMillis() - start) );

// run the above example code here
log.info("Total time to send/receive data = " + new Long(System.currentTimeMillis() - start) );

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

для получения информации о закрытии соединений, о которых вы не спрашивали, см. в Java когда закрывается URL-соединение?.

Тим Брей представил краткий шаг за шагом, заявив, что openConnection() не устанавливает фактическое соединение. Скорее, фактическое HTTP-соединение не устанавливается до тех пор, пока вы не вызовете такие методы, как getInputStream() или getOutputStream().

http://www.tbray.org/ongoing/When/201x/2012/01/17/HttpURLConnection

на каком этапе HTTPURLConnection пытается установить соединение с данным URL-адресом?

на порту, названном в URL, если таковой имеется, в противном случае 80 для HTTP и 443 для HTTPS. Я считаю, что это задокументировано.

на каком этапе я могу знать, что мне удалось успешно установить соединение?

при вызове getInputStream() или getOutputStream() или getResponseCode () без получения исключения.

устанавливают соединение и отправляют фактический запрос, выполненный за один шаг/вызов метода? Что это за метод?

нет и нет.

можете ли вы объяснить функцию getOutputStream и getInputStream в термине непрофессионала?

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

Я замечаю, что когда сервер, к которому я пытаюсь подключиться, не работает, я получаю исключение getOutputStream. Означает ли это, что HTTPURLConnection начнет устанавливать соединение только при вызове getOutputStream? Как насчет getInputStream? Поскольку я могу получить ответ только в getInputStream, то означает ли это, что я еще не отправил запрос в getOutputStream, а просто установил соединение? HttpURLConnection возвращается на сервер, чтобы запросить ответ при вызове getInputStream?

см. выше.

Я правильно сказать, что openConnection просто создает новый объект соединения, но еще не устанавливает никакого соединения?

да.

Как я могу измерить накладные расходы на чтение и подключить накладные расходы?

Connect: возьмите время getInoutStream() или getOutputStream (), чтобы вернуться, в зависимости от того, что вы вызываете первым. Чтение: время от начала первого чтения до получения EOS.

на каком этапе HTTPURLConnection пытается установить соединение с данным URL-адресом?

Это стоит уточнить, есть 'UrlConnection' экземпляр и тогда есть базовый Tcp/Ip / SSL socket connection, 2 разных понятия. Экземпляр' UrlConnection 'или' HttpUrlConnection ' является синонимом одного запроса страницы HTTP и создается при вызове url.содержащие вредоносные элементы(). Но если вы делаете несколько url-адрес.openConnection () 'S от одного экземпляра "url", то если Вам повезет, они будут повторно использовать один и тот же сокет Tcp/Ip и SSL-квитирование...что хорошо, если вы делаете много запросов страниц на один и тот же сервер, особенно хорошо, если вы используете SSL, где накладные расходы на установку сокета очень высоки.

посмотреть: реализация HttpURLConnection

Comments

    Ничего не найдено.