在 Android 上使用 HttpURLConnection
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2389757/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using HttpURLConnection on Android
提问by David Read
I am trying to connect a web server I have running in my android App however for some reason it's failing.
我正在尝试连接在我的 android 应用程序中运行的网络服务器,但是由于某种原因它失败了。
I can connect to the webpage normally and using my phone's browser, I can also use the below code to connect to google but for some reason my code will not connect to my web server. If I host the server on port 80 I get error code 503 every time, if I host it on 8080 (which is preferable) I get a timeout exception which is below.
我可以使用手机浏览器正常连接到网页,我也可以使用以下代码连接到谷歌,但由于某种原因,我的代码无法连接到我的网络服务器。如果我在端口 80 上托管服务器,我每次都会收到错误代码 503,如果我在 8080 上托管它(这是可取的),我会收到下面的超时异常。
03-05 20:12:22.432: WARN/System.err(29254): java.net.SocketException: The operation timed out
03-05 20:12:22.602: WARN/System.err(29254): at org.apache.harmony.luni.platform.OSNetworkSystem.connectSocketImpl(Native Method)
03-05 20:12:22.602: WARN/System.err(29254): at org.apache.harmony.luni.platform.OSNetworkSystem.connect(OSNetworkSystem.java:125)
03-05 20:12:22.602: WARN/System.err(29254): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:227)
03-05 20:12:22.612: WARN/System.err(29254): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:521)
03-05 20:12:22.612: WARN/System.err(29254): at java.net.Socket.connect(Socket.java:1019)
03-05 20:12:22.612: WARN/System.err(29254): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>(HttpConnection.java:67)
03-05 20:12:22.612: WARN/System.err(29254): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionManager$ConnectionPool.getHttpConnection(HttpConnectionManager.java:151)
03-05 20:12:22.612: WARN/System.err(29254): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionManager.getConnection(HttpConnectionManager.java:73)
03-05 20:12:22.612: WARN/System.err(29254): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.getHTTPConnection(HttpURLConnection.java:826)
03-05 20:12:22.612: WARN/System.err(29254): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:812)
03-05 20:12:22.612: WARN/System.err(29254): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.getResponseCode(HttpURLConnection.java:1275)
03-05 20:12:22.612: WARN/System.err(29254): at com.project.library.remailer.ServerSelect.downloadDirectory(ServerSelect.java:84)
03-05 20:12:22.622: WARN/System.err(29254): at com.project.main.NewMessage.run(NewMessage.java:156)
The code is:
代码是:
try {
URL url = new URL(directoryLocation);
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
// The line below is where the exception is called
int response = httpURLConnection.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
// Response successful
InputStream inputStream = httpURLConnection.getInputStream();
// Parse it line by line
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(inputStream));
String temp;
while ((temp = bufferedReader.readLine()) != null) {
// Parsing of data here
}
} else {
Log.e("SAMES", "INCORRECT RETURN CODE: " + response);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
When I try the code in the link suggested by CommonsWare for port 8080 I get the same error as before, the timeout exception. For port 80 I get the following exception, both of these errors occur on the url.openStream().
当我尝试使用 CommonsWare 为端口 8080 建议的链接中的代码时,我得到与以前相同的错误,即超时异常。对于端口 80,我收到以下异常,这两个错误都发生在 url.openStream() 上。
Port 80 exception:
端口 80 异常:
03-06 11:53:53.296: WARN/System.err(639): java.io.FileNotFoundException: http://64.197.194.165:80/path
03-06 11:53:53.376: WARN/System.err(639): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1064)
03-06 11:53:53.376: WARN/System.err(639): at java.net.URL.openStream(URL.java:674)
03-06 11:53:53.376: WARN/System.err(639): at com.project.library.remailer.ServerSelect.downloadDirectory(ServerSelect.java:118)
03-06 11:53:53.376: WARN/System.err(639): at com.project.main.NewMessage.run(NewMessage.java:156)
I also tried using the following code:
我还尝试使用以下代码:
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(directoryLocation);
try
{
HttpResponse response = client.execute(request);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line;
while((line = reader.readLine()) != null) {
Log.e("SAMES", line);
}
}
catch(Exception e)
{
e.printStackTrace();
}
However that has resulted in the same timeout error for port 8080, which occurs when client.execute(response) is called.
但是,这导致了端口 8080 的相同超时错误,这在调用 client.execute(response) 时发生。
For port 80 I get a webpage which says that it couldn't connect, which alot of HTML editing, however the main thing it says on the page is:
对于端口 80,我得到一个网页,说它无法连接,其中进行了大量 HTML 编辑,但是它在页面上说的主要内容是:
03-06 13:10:23.576: ERROR/SAMES(1267): The Web Server may be down, too busy, or experiencing other problems preventing it from responding to requests. You may wish to try again at a later time.
03-06 13:10:23.576:错误/相同(1267):Web 服务器可能已关闭、太忙或遇到其他问题,阻止它响应请求。您可能希望稍后再试。
回答by CommonsWare
Various notes:
各种注意事项:
- You don't indicate where the timeout occurred.
- You might try this example, which uses URL differently than you are.
- Your error code 503 on port 80 should result in some error information on your server that might be useful.
- Are there any proxy servers or other things between your phone and the Web server?
- Have you tried with both WiFi and 3G?
- You might try switching to HttpClient and see if you get better results or perhaps a better error message.
- 您没有指出超时发生的位置。
- 您可以试试这个示例,它使用的 URL 与您不同。
- 您在端口 80 上的错误代码 503 应该会在您的服务器上产生一些可能有用的错误信息。
- 您的手机和 Web 服务器之间是否有任何代理服务器或其他东西?
- 您是否尝试过同时使用 WiFi 和 3G?
- 您可以尝试切换到 HttpClient 并查看是否获得更好的结果或更好的错误消息。
回答by andr
Your issue is too complex (in my opinion) to address it fully, so I'd like to share my findings on a problem I've been having recently, which caused exactly what you described in your comment:
您的问题太复杂(在我看来)无法完全解决,因此我想分享我对最近遇到的问题的发现,该问题正是您在评论中描述的原因:
// The line below is where the exception is called
int response = httpURLConnection.getResponseCode();
That same piece of code caused IOExceptionin one of my classes - every time, on every valid URL, so it was clear the problem was in the code - which looked the same as yours - simple, no headers set, nothing above tutorial-like examples. I then noticed that every example I've seen was not even calling URLConnection.connect()method - so I thought: when does the actual connection occur? What does standard HttpURLConnectionuse pattern look like?
IOException在我的一个类中引起的同一段代码- 每次,在每个有效URL,所以很明显问题出在代码中 - 看起来和你的一样 - 简单,没有设置标题,上面没有类似教程的示例。然后我注意到我看到的每个例子甚至都没有调用URLConnection.connect()方法 - 所以我想:实际连接什么时候发生?标准HttpURLConnection使用模式是什么样的?
Unfortunately, the documentation is scarce on that topic. So I've done some googling and found this blog post: HttpURLConnection's Dark Secrets - by Tim Braywhich was invaluable in writing more complex HttpURLConnectionuse-ceses. It also provided an answer to my problem - let me quote relevant lines:
不幸的是,有关该主题的文档很少。所以我做了一些谷歌搜索并找到了这篇博文:HttpURLConnection's Dark Secrets - 作者 Tim Bray,这对于编写更复杂的HttpURLConnection用例非常宝贵。它还为我的问题提供了答案——让我引用相关的话:
// this opens a connection, then sends GET & headers
in = conn.getInputStream();
// can't get status before getInputStream. If you try, you'll
// get a nasty exception.
http_status = conn.getResponseCode();
// better check it first
if (http_status / 100 != 2) {
// redirects, server errors, lions and tigers and bears! Oh my!
}
See the 1st and 2nd comment? Well, that makes a lot of sense when you know that actual network connection is initiated by HttpURLConnection.getInputStream()(HttpURLConnection.getOutputStream()if you're sending any content to the server). Placing invocation of getResponseCode()aftergetInputStream()fixed my problem.
看到第一条和第二条评论了吗?好吧,当您知道实际的网络连接是由HttpURLConnection.getInputStream()(HttpURLConnection.getOutputStream()如果您要向服务器发送任何内容)启动时,这很有意义。调用getResponseCode()aftergetInputStream()解决了我的问题。
回答by Dan Lew
What happens if you try calling httpURLConnection.connect()after calling url.openConnection()?
如果您在调用httpURLConnection.connect()后尝试调用会发生什么url.openConnection()?
回答by VittyO
Only an app with root permissions can open ports below 1024 - that's the issue with port 80.
只有具有 root 权限的应用程序才能打开 1024 以下的端口 - 这就是端口 80 的问题。

