在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; } 

  • 适用于Android的JDBC与Web服务
  • OkHttp - 启用日志
  • JSON Java检查元素是JSONArray或JSONObject
  • 实施C2DM注册的最佳实践
  • 使用Ksoap2(Android)检查信封
  • Android:在共享首选项中存储身份validation令牌是一个好主意吗?
  • 从Android上传图像到Amazon S3?
  • 如何validationWeb服务调用的来源
  • 看看你的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"); } 

    等等…