我正在访问服务器以进行Web服务调用。当我在与服务器相同的网络上进行开发时,我可以通过其内部IP地址访问Web服务,但不能访问其外部IP地址。但是,如果我不在网络上,我只能通过其外部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;
}
答案 0 :(得分:4)
查看自己的Android的IP地址。你可以像stated here那样得到它。
然后你可以决定:
答案 1 :(得分:3)
基于harism的非常好的评论,我只需使用静态布尔值来选择IP,从而避免每次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;
答案 2 :(得分:3)
这不是您可以在软件中轻松修复的内容。我认为正确的答案是修复将流量路由到内部Web服务器的过滤器/配置,或者通过正确配置DNS以根据您所在的位置(网络内部或外部)返回正确的IP。更多信息可以在这里找到:
Accessing internal network resource using external IP address
并通过谷歌搜索“外部IP在内部网络上不起作用”
答案 3 :(得分:3)
您可以将重试代码放在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;
}
注意:像大多数人所说的那样,这对于生产版本来说可能不是一个很好的解决方案,但是对于测试它可能会很好。
答案 4 :(得分:1)
您可以更改retrieve()调用以将主机作为参数。在启动时,尝试ping每个可能的主机。对一些返回非常快的东西(比如可能是测试页面)进行简单的检索调用。完成您想要尝试的每个可能的主机。找到有效的一个后,保存该主机并将其用于将来的所有呼叫。
答案 5 :(得分:1)
第1,你应该能够在运行时处理这个案例。我非常强烈推荐vs不同版本。例如:尝试外部,如果内部失败。
同时有些启发式:
内部IP意味着网络是相同的。所以你可以检查它,如果它是相同的尝试内部地址1st,否则外部优先。
稍后,将本地IP地址的映射保存到成功连接的地址,然后查找以更改优先级。
分辨率本身可以通过超时请求服务器的根“/”来进行(如果您愿意,可以使用2个不同的线程同时执行任务)。
此外,如果您可以访问路由器/防火墙,则可以识别外部地址并正确处理它。因此,您最终可以使用正常工作的外部地址。
答案 6 :(得分:1)
我会将这种特定于环境的信息放在properties file(或者某种配置文件)中。您只需要一行文件(显然您可以根据需要更改IP地址):
serverUrl=192.168.1.1
Java已经具有用于读取和写入这些类型文件的内置功能(请参阅上面的链接)。您还可以在此文件中保留数据库连接信息等。任何环境特定的东西。
在您的代码中,您似乎使用常量来保存服务器URL。我不建议这样做。服务器URL更改时会发生什么?您需要修改和重新编译代码。但是,使用配置文件,不需要更改代码。
答案 7 :(得分:0)
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");
}
等...