你能解释一下HttpURLConnection的连接过程?你能解释一下HttpURLConnecti

2019-05-13 12:26发布

我使用HTTPURLConnection连接到Web服务。 我知道如何使用HTTPURLConnection ,但我想了解它是如何工作的。 基本上,我想了解以下内容:

  • 在这点也HTTPURLConnection试图建立到给定URL的连接?
  • 在这一点上,我可以知道我是能够成功地建立连接?
  • 正在建立一个连接,并发送一个步骤/方法调用完成的实际要求? 用什么方法呢?
  • 你能解释的功能getOutputStreamgetInputStream外行的任期? 我注意到,当我试图连接到服务器宕机,我得到一个ExceptiongetOutputStream 。 这是否意味着HTTPURLConnection才会开始时,我调用建立连接getOutputStream ? 怎么样getInputStream ? 由于我只能够得到的响应getInputStream ,那么这是否意味着我根本不发送任何请求getOutputStream又而是简单地建立连接? 不要HttpURLConnection返回到服务器以请求响应时,我援引getInputStream
  • 我是正确的说openConnection简单地创建一个新的连接对象,但不建立任何联系了吗?
  • 我怎样才能衡量阅读开销和连接开销?

Answer 1:

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或的getInputStream url.openConnection()您向服务器发送一个请求建立连接。 存在着发生在服务器发回的连接建立确认给你握手。 它是那么在那个时间你准备发送或接收数据点。 因此,你并不需要调用的getOutputStream 建立连接打开一个流,除非你对提出请求的目的是为了发送数据。

通俗地说,做出getInputStream请求打电话给你的朋友的房子说相当于“嘿,是不是好,如果我过来借用对副交手的?” 和你的朋友说,建立握手“当然!来吧,得到它”。 然后,在这一点上,在建立连接,你走你的朋友家,敲门,要求副交手,往回走,去你家。

使用一个类似的例子getOutputStream会涉及调用你的朋友,说:“嗨,我有那钱我欠你的,我可以将它发送给你”? 您的朋友,需要钱,生病里面,你保持了这么久,说:“当然,到这儿来,你贱骨头”。 所以你步行到您的朋友的房子,“POST”钱给他。 然后,他踢你出去,你走回你的房子。

现在,在外行的例子继续,让我们来看看一些例外。 如果你叫你的朋友,他不在家,这可能是一个500错误。 如果你打电话,因为你的朋友是你累借钱所有的时间得到了一个断开号消息,这是一个404页未找到。 如果您的手机是死了,因为你没有埋单,这可能是一个IOException。 (注意:此部分可能不是100%正确的它旨在让你发生了什么通俗地说的总体思路。)

问题5:

是的,你是正确的,根本的openConnection创建一个新的连接对象,但不建立它。 当你打电话或者的getInputStream或getOutputStream方法建立连接。

openConnection创建一个新的连接对象。 从URL.openConnection的javadoc :

一个新的连接是通过调用协议处理程序此URL的openConnection来打开每一次。

当你打电话的openConnection建立连接,并为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连接关闭? 。



Answer 2:

蒂姆·布雷提出了一个简洁的一步一步,指出的openConnection()不建立一个实际的连接。 更确切地说,是不成立的一个实际的HTTP连接,直到你调用如的getInputStream()或的getOutputStream()。

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



Answer 3:

在这点也HttpURLConnection类试图建立到给定URL的连接?

在URL中如果有命名的端口,否则80用于HTTP和443用于HTTPS。 我相信,这是记录在案。

在这一点上,我可以知道我是能够成功地建立连接?

当你调用的getInputStream()或的getOutputStream()或getResponseCode()没有得到一个例外。

正在建立一个连接,并发送一个步骤/方法调用完成的实际要求? 用什么方法呢?

没有,没有。

你能解释的getOutputStream和的getInputStream在外行的任期功能?

无论是他们的第一次连接如果必要的话,然后返回所需的流。

我注意到,当我试图连接到服务器宕机,我得到的getOutputStream异常。 这是否意味着HttpURLConnection类才会开始时,我援引的getOutputStream建立连接? 怎么样的getInputStream? 由于我只能够得到在的getInputStream的响应,那么岂不是我没有的getOutputStream发送任何请求,但只是简单建立连接? 不要HttpURLConnection类返回到服务器以请求响应时,我援引的getInputStream?

往上看。

我是正确的说,仅仅的openConnection创建一个新的连接对象,但不建立任何联系了吗?

是。

我怎样才能衡量阅读开销和连接开销?

连接:走的时候getInoutStream()或的getOutputStream()将返回,无论你先打电话。 阅读:时间从开始第一次读到获得EOS。



Answer 4:

在这点也HttpURLConnection类试图建立到给定URL的连接?

这是值得澄清,有个'URLConnection的实例 ,然后有潜在的TCP / IP / SSL套接字连接 ,2个不同的概念。 在“的URLConnection”或“HttpURLConnection的”实例是一个单一的HTTP页面请求的代名词,并在创建,当你调用url.openConnection()。 但是,如果你做多的url.openConnection()'从一个S‘链接’实例,然后如果你是幸运的,他们会重复使用同一个TCP / IP套接字和SSL握手的东西......如果你这是个好如果你使用SSL那里建立socket的开销是非常高的做大量的页面请求到同一台服务器,特别好。

请参阅: HttpURLConnection的实施



文章来源: Can you explain the HttpURLConnection connection process?