在 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 IOException
in 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 HttpURLConnection
use 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 HttpURLConnection
use-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 的问题。