你能解释一下HttpURLConnection连接过程吗? [英] Can you explain the HttpURLConnection connection process?

查看:158
本文介绍了你能解释一下HttpURLConnection连接过程吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using HTTPURLConnection to connect to a web service. I know how to use HTTPURLConnection but I want to understand how it works. Basically, I want to know the following:


  • 在哪一点 HTTPURLConnection 尝试建立与给定URL的连接?

  • 我可以在哪一点知道我能够成功建立连接?

  • 正在建立一个连接和发送一步/方法调用完成的实际请求?它是什么方法?

  • 你能解释一下 getOutputStream getInputStream 外行人的任期?我注意到当我尝试连接的服务器关闭时,我在 getOutputStream 处得到 Exception 。这是否意味着 HTTPURLConnection 只会在我调用 getOutputStream 时才开始建立连接? getInputStream 怎么样?由于我只能在 getInputStream 获得响应,这是否意味着我没有在 getOutputStream发送任何请求但是只是建立连接?当我调用 getInputStream 时, HttpURLConnection 返回服务器请求响应?

  • 我是否正确地说 openConnection 只是创建一个新的连接对象但是还没有建立任何连接?

  • 怎么能我测量读取开销并连接开销?

  • On which point does HTTPURLConnection try to establish a connection to the given URL?
  • On which point can I know that I was able to successfully establish a connection?
  • Are establishing a connection and sending the actual request done in one step/method call? What method is it?
  • Can you explain the function of getOutputStream and getInputStream in layman's term? I notice that when the server I'm trying to connect to is down, I get an Exception at getOutputStream. Does it mean that HTTPURLConnection will only start to establish a connection when I invoke getOutputStream? How about the getInputStream? Since I'm only able to get the response at getInputStream, then does it mean that I didn't send any request at getOutputStream yet but simply establishes a connection? Do HttpURLConnection go back to the server to request for response when I invoke getInputStream?
  • Am I correct to say that openConnection simply creates a new connection object but does not establish any connection yet?
  • How can I measure the read overhead and connect overhead?

推荐答案

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上面。

The first 3 answers to your questions are listed as inline comments, beside each method, in the example HTTP POST above.

来自 getOutputStream


返回写入此连接的输出流。

Returns an output stream that writes to this connection.

基本上,我认为你对它的运作方式有很好的理解,所以让我以外行的方式重申一下。 getOutputStream 基本上打开一个连接流,目的是将数据写入服务器。在上面的代码示例中,message可以是我们发送到服务器的注释,该注释表示帖子上留下的评论。当你看到 getOutputStream 时,你打开连接流进行写入,但是在你调用<$ c之前你实际上并没有写任何数据$ c> writer.write(message =+ message);

Basically, I think you have a good understanding of how this works, so let me just reiterate in layman's terms. getOutputStream basically opens a connection stream, with the intention of writing data to the server. In the above code example "message" could be a comment that we're sending to the server that represents a comment left on a post. When you see getOutputStream, you're opening the connection stream for writing, but you don't actually write any data until you call writer.write("message=" + message);.

来自 getInputStream()


返回从此打开的连接读取的输入流。如果读取超时在数据可用于读取之前到期,则从返回的输入流读取时可以抛出SocketTimeoutException。

Returns an input stream that reads from this open connection. A SocketTimeoutException can be thrown when reading from the returned input stream if the read timeout expires before data is available for read.

getInputStream 相反。与 getOutputStream 一样,它也会打开连接流,但目的是从服务器读取数据,而不是写入数据。如果连接或流开放失败,您将看到 SocketTimeoutException

getInputStream does the opposite. Like getOutputStream, it also opens a connection stream, but the intent is to read data from the server, not write to it. If the connection or stream-opening fails, you'll see a SocketTimeoutException.


getInputStream怎么样?因为我只能在getInputStream上获得响应,那么它是否意味着我还没有在getOutputStream发送任何请求但只是建立连接?

How about the getInputStream? Since I'm only able to get the response at getInputStream, then does it mean that I didn't send any request at getOutputStream yet but simply establishes a connection?

请记住,发送请求和发送数据是两种不同的操作。当您调用 getOutputStream或getInputStream url.openConnection()时,您向服务器发送请求以建立连接。发生握手,服务器向您发回确认连接已建立的确认。然后,在那个时间点,您准备发送或接收数据。因此,您不需要调用getOutputStream来建立连接打开一个流,除非您发出请求的目的是发送数据。

Keep in mind that sending a request and sending data are two different operations. When you invoke getOutputStream or getInputStream url.openConnection(), you send a request to the server to establish a connection. There is a handshake that occurs where the server sends back an acknowledgement to you that the connection is established. It is then at that point in time that you're prepared to send or receive data. Thus, you do not need to call getOutputStream to establish a connection open a stream, unless your purpose for making the request is to send data.

用外行人的话来说,制作一个 getInputStream 请求相当于打电话给你朋友的房子说嘿,如果我过来借这一对就可以了副手柄?并且你的朋友说:当然!来吧,得到它。然后,在那时,连接完成,你走到你朋友家,敲门,请求副把手,然后走回你家。

In layman's terms, making a getInputStream request is the equivalent of making a phone call to your friend's house to say "Hey, is it okay if I come over and borrow that pair of vice grips?" and your friend establishes the handshake by saying, "Sure! Come and get it". Then, at that point, the connection is made, you walk to your friend's house, knock on the door, request the vice grips, and walk back to your house.

使用 getOutputStream 的类似示例将涉及给您的朋友打电话并说嘿,我有我欠你的钱,我可以把它寄给你吗?你的朋友,你需要钱和生病才能保存这么长时间,他说:当然,过来你这个便宜的混蛋。所以你走到你朋友的家里并把钱邮寄给他。然后他把你踢出去,然后你走回家。

Using a similar example for getOutputStream would involve calling your friend and saying "Hey, I have that money I owe you, can I send it to you"? Your friend, needing money and sick inside that you kept it for so long, says "Sure, come on over you cheap bastard". So you walk to your friend's house and "POST" the money to him. He then kicks you out and you walk back to your house.

现在,继续这个外行的例子,让我们来看看一些例外情况。如果你打电话给你的朋友并且他不在家,那可能是500错误。如果您打电话并收到断开连接的号码消息,因为您的朋友已经厌倦了您一直借钱,那就是找不到404页面。如果您的手机因为没有支付账单而死亡,那可能是IOException。 (注意:此部分可能不是100%正确。它旨在让您大致了解外行人的条款。)

Now, continuing with the layman's example, let's look at some Exceptions. If you called your friend and he wasn't home, that could be a 500 error. If you called and got a disconnected number message because your friend is tired of you borrowing money all the time, that's a 404 page not found. If your phone is dead because you didn't pay the bill, that could be an IOException. (NOTE: This section may not be 100% correct. It's intended to give you a general idea of what's happening in layman's terms.)

问题#5:

是的,你是正确的,openConnection只是创建一个新的连接对象,但没有建立它。当您调用getInputStream或getOutputStream时建立连接。

openConnection 创建一个新的连接对象。来自 URL.openConnection javadocs

openConnection creates a new connection object. From the URL.openConnection javadocs:


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

A new connection is opened every time by calling the openConnection method of the protocol handler for this URL.

当您调用openConnection时建立连接,并在实例化时调用InputStream,OutputStream或两者。

The connection is established when you call openConnection, and the InputStream, OutputStream, or both, are called when you instantiate them.

问题#6

为了衡量开销,我通常会在整个连接周围包含一些非常简单的时序代码块,如下所示:

To measure the overhead, I generally wrap some very simple timing code around the entire connection block, like so:

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) );

我确信有更多高级方法可以测量请求时间和开销,但这通常是足以满足我的需求。

I'm sure there are more advanced methods for measuring the request time and overhead, but this generally is sufficient for my needs.

有关关闭连接的信息,请参阅在Java中何时关闭URL连接?

For information on closing connections, which you didn't ask about, see In Java when does a URL connection close?.

这篇关于你能解释一下HttpURLConnection连接过程吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆