在android的IP后备

我正在访问一个服务器的Web服务调用。 当我在服务器的同一networking上开发时,我可以通过其内部IP地址访问Web服务,但不能访问其外部IP地址。 但是,如果我不在networking上,我只能通过外部IP地址访问它。 尝试其中一个IP地址然后又回到另一个IP地址的最佳方式是什么?

下面是我的代码只访问一个或另一个的示例:

protected String retrieve() { Log.v(TAG, "retrieving data from url: " + getURL()); HttpPost request = new HttpPost(getURL()); try { StringEntity body = new StringEntity(getBody()); body.setContentType(APPLICATION_XML_CONTENT_TYPE); request.setEntity(body); HttpConnectionParams.setConnectionTimeout(client.getParams(), CONNECTION_TIMEOUT); HttpConnectionParams.setSoTimeout(client.getParams(), SOCKET_TIMEOUT); HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { Log.e(TAG, "the URL " + getURL() + " returned the status code: " + statusCode + "."); return null; } HttpEntity getResponseEntity = response.getEntity(); if (getResponseEntity != null) { return EntityUtils.toString(getResponseEntity); } } catch (IOException e) { Log.e(TAG, "error retrieving data.", e); request.abort(); } return null; } /* * @return the URL which should be called. */ protected String getURL() { return INTERNAL_SERVER_URL + WEB_APP_PATH; } 

Solutions Collecting From Web of "在android的IP后备"

看看你的android的自己的IP地址。 你可以像这里所述的那样得到它。

那么你可以决定:

  • 如果你在你的办公室的子网(例如192.168.0.0/16) – 使用内部地址
  • 如果你在其他子网 – 使用外部地址

基于harism的非常好的评论,我会简单地使用一个静态的布尔值来selectIP,从而避免每次ping错IP:

 public static final Boolean IS_DEBUG = true; // or false // all your code here if (DEBUG) ip = xxx.xxx.xxx.xxx; else ip = yyy.yyy.yyy.yyy; 

这不完全是你可以在软件中轻松修复的东西。 我认为正确的答案是修复将stream量路由到内部Web服务器的filter/configuration,或者通过正确configurationDNS根据您所在的位置(networking内部或外部)返回适当的IP。 更多信息可以在这里find:

使用外部IP地址访问内部networking资源

http://www.astaro.org/astaro-gateway-products/network-security-firewall-nat-qos-ips-more/6704-cant-acces-internal-webserver-via-external-ip.html

并通过谷歌search“外部IP不能在内部networking上工作”

您可以将重试代码放入IOException的catch子句中

 protected String retrieve(String url) { Log.v(TAG, "retrieving data from url: " + url); HttpPost request = new HttpPost(url); try { StringEntity body = new StringEntity(getBody()); body.setContentType(APPLICATION_XML_CONTENT_TYPE); request.setEntity(body); HttpConnectionParams.setConnectionTimeout(client.getParams(), CONNECTION_TIMEOUT); HttpConnectionParams.setSoTimeout(client.getParams(), SOCKET_TIMEOUT); HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { Log.e(TAG, "the URL " + getURL() + " returned the status code: " + statusCode + "."); return null; } HttpEntity getResponseEntity = response.getEntity(); if (getResponseEntity != null) { return EntityUtils.toString(getResponseEntity); } } catch (IOException e) { if(url.equals(EXTERNAL_URL){ return retrieve(INTERNAL_URL); } Log.e(TAG, "error retrieving data.", e); request.abort(); } return null; } 

注意:正如大多数人所说,这可能不是一个生产版本的很好的解决scheme,但testing它可能会工作得很好。

您可以更改您的retrieve()调用以将主机作为参数。 在启动时,尝试ping每个可能的主机。 做一个简单的检索调用返回非常快的东西(如也许testing页)。 通过你想尝试的每个可能的主机工作。 一旦你find一个工作,保存该主机,并将其用于所有未来的呼叫。

第一,你应该能够处理运行时的情况。 我强烈build议与不同的版本。例如:尝试外部,如果内部失败。

一些启发式的同时:
内部IP意味着networking是一样的。 所以你可以检查它,如果是相同的尝试内部地址1st,否则外部优先。 稍后,保存本地IP地址到成功连接的地址的映射并查找它以改变优先级。

解决scheme本身可以通过请求超时服务器的根“/”来进行(如果你愿意的话,可以同时使用2个不同的线程来执行任务)。

此外,如果您有权访问路由器/防火墙,则可以识别外部地址并正确处理它。 所以你可以结束与正常工作的外部地址。

我会把这种环境特定的信息放在一个属性文件 (或者某种configuration文件)中。 所有你需要的是一行文件(显然你会改变你的IP地址):

 serverUrl=192.168.1.1 

Java已经具有读写这类文件的内置function(参见上面的链接)。 你也可以在这个文件中保存数据库连接信息等。 任何环境特定的真的。

在你的代码中,看起来你正在使用常量来保存服务器的URL。 我不会build议。 服务器URL更改时会发生什么? 你需要修改和重新编译你的代码。 但是使用configuration文件,不需要更改代码。

 import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; 

和:

 HttpClient client = new HttpClient(); HttpMethod method = new GetMethod("http://www.myinnersite.com"); int responseCode = client.executeMethod(method); if (responseCode != 200) { method = new GetMethod("http://www.myoutersite.com"); } 

等等…