在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:39:49  来源:igfitidea点击:

Using HttpURLConnection on Android

androidwebserverhttpurlconnection

提问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 的问题。