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

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

  • HTTPURLConnection试图build立到给定URL的连接?
  • 我能在哪一点知道我能够成功build立连接?
  • 正在build立一个连接,并发送一个步骤/方法调用完成的实际请求? 它是什么方法?
  • 你能解释一下getOutputStreamgetInputStream的外行人的function吗? 我注意到,当我试图连接的服务器closures时, getOutputStream出现Exception 。 这是否意味着当我调用getOutputStream时, HTTPURLConnection才会开始build立连接? getInputStream怎么样? 因为我只能得到在getInputStream响应,那么这是否意味着我没有发送任何请求在getOutputStream ,但只是build立一个连接? 当我调用getInputStream时, HttpURLConnection是否会回到服务器请求响应?
  • 我正确地说, openConnection只是创build一个新的连接对象,但不build立任何连接呢?
  • 我如何测量读取开销和连接开销?
 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 :

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

基本上,我认为你对这是如何工作的有一个很好的理解,所以让我以外行人的口吻重申一遍。 getOutputStream基本上打开了一个连接stream,意图将数据写入服务器。 在上面的代码示例中,“消息”可以是我们发送给服务器的评论,代表留言在留言上。 当你看到getOutputStream ,你打开连接stream进行写入,但是直到调用writer.write("message=" + message);

从getInputStream() :

返回从此打开的连接读取的inputstream。 如果在读取数据可用之前读取超时到期,则从返回的inputstream读取时可能会抛出SocketTimeoutException。

getInputStream做相反的getInputStream 。 像getOutputStream一样,它也打开一个连接stream,但意图是从服务器读取数据,而不是写入它。 如果连接或stream打开失败,您将看到一个SocketTimeoutException

getInputStream怎么样? 因为我只能得到在getInputStream的响应,那么这是否意味着我没有发送任何请求getOutputStream,但只是build立一个连接?

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

用通俗的话来说, getInputStream请求就好像是打个电话给你的朋友的房子说:“嘿,如果我过来借那副副手柄,好吗? 和你的朋友build立握手,说:“当然!来吧,得到它”。 然后,在这一点上,build立联系,你走到你的朋友家,敲门,请求副手,走回你的房子。

getOutputStream使用一个类似的例子将涉及到打电话给你的朋友,并说:“嘿,我有我欠你的钱,我可以把它发送给你”? 你的朋友,需要钱和生病在里面,你保持了这么久,说:“当然,超过你便宜的混蛋。 所以你走到你的朋友家,把钱“寄”给他。 然后他把你踢出去,你走回你的房子。

现在,继续外行的例子,让我们看看一些例外。 如果你打电话给你的朋友,而他不在家,那可能是500错误。 如果你打电话,并得到一个断开的号码消息,因为你的朋友厌倦了你一直借钱,这是一个404页面没有find。 如果您的手机因为没有付账而死机,那可能是IOException。 (注意:这部分可能不是100%正确的,它是为了给你一个关于外行人情况的一般概念。)

问题5:

是的,你是正确的openConnection只是创build一个新的连接对象,但不build立它。 在调用getInputStream或getOutputStream时build立连接。

openConnection创build一个新的连接对象。 从URL.openConnection javadocs :

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

当您调用openConnection时build立连接,并在实例化它们时调用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) ); 

我相信有更先进的方法来测量请求时间和开销,但这通常足以满足我的需求。

有关closures连接的信息,请参阅Java中关于URL连接的内容。 。

Tim Bray提出了一个简洁的步骤,指出openConnection()不build立实际的连接。 相反,实际的HTTP连接在您调用诸如getInputStream()或getOutputStream()之类的方法之前并不会build立。

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

HTTPURLConnection试图build立到给定URL的连接?

在URL中指定的端口(如果有),否则为80,HTTP和443为HTTPS。 我相信这是logging。

我能在哪一点知道我能够成功build立连接?

当您调用getInputStream()或getOutputStream()或getResponseCode()而不会发生exception。

正在build立一个连接,并发送一个步骤/方法调用完成的实际请求? 它是什么方法?

没有,也没有。

你能解释一下getOutputStream和getInputStream的外行人的function吗?

它们中的任何一个如果需要,首先连接,然后返回所需的stream。

我注意到,当我试图连接的服务器closures时,getOutputStream出现exception。 这是否意味着当我调用getOutputStream时,HTTPURLConnection才会开始build立连接? getInputStream怎么样? 因为我只能得到在getInputStream的响应,那么这是否意味着我没有发送任何请求getOutputStream,但只是build立一个连接? 当我调用getInputStream时,HttpURLConnection是否返回服务器以请求响应?

往上看。

我正确地说,openConnection只是创build一个新的连接对象,但不build立任何连接呢?

是。

我如何测量读取开销和连接开销?

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

HTTPURLConnection试图build立到给定URL的连接?

值得澄清的是,有'UrlConnection'实例 ,然后是底层的TCP / IP / SSL套接字连接 ,有两个不同的概念。 “UrlConnection”或“HttpUrlConnection”实例与单个HTTP页面请求同义,并在调用url.openConnection()时创build。 但是,如果你从一个“url”实例中执行多个url.openConnection(),那么如果你幸运的话,他们将重复使用相同的Tcp / Ip套接字和SSL握手的东西…这是好的,如果你向同一台服务器做大量的页面请求,特别是在build立套接字的开销非常高的情况下使用SSL的情况下。

请参阅: HttpURLConnection实现