你能解释一下HttpURLConnection的连接过程吗?
我正在使用HTTPURLConnection
连接到Web服务。 我知道如何使用HTTPURLConnection
但我想了解它是如何工作的。 基本上,我想知道以下几点:
-
HTTPURLConnection
试图build立到给定URL的连接? - 我能在哪一点知道我能够成功build立连接?
- 正在build立一个连接,并发送一个步骤/方法调用完成的实际请求? 它是什么方法?
- 你能解释一下
getOutputStream
和getInputStream
的外行人的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实现
- 如何检查InputStream是否被压缩?
- HttpURLConnection.getResponseCode()在第二次调用时返回-1
- Android HttpsUrlConnection eofexception
- Java – 通过POST方法轻松发送HTTP参数
- Android的HTTPUrlConnection:如何设置发布数据在http身上?
- 从Android发送JSON HTTP POST请求
- 如何在Java中发送Https Post请求
- FileNotFoundException从HttpURLConnection获取InputStream对象
- 获取java.net.SocketTimeoutException:连接在android中超时