IP-резерв в Android - PullRequest
       12

IP-резерв в Android

7 голосов
/ 14 мая 2011

Я получаю доступ к серверу для вызовов веб-службы.Когда я работаю в той же сети, что и сервер, я могу получить доступ к веб-службе по ее внутреннему 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;
}

Ответы [ 8 ]

4 голосов
/ 03 июня 2011

Посмотрите на собственный IP-адрес вашего андроида.Вы можете получить его как , указанное здесь .

Затем вы можете решить:

  • , если вы находитесь в подсети вашего офиса (например, 192.168.0.0/16)- используйте внутренний адрес
  • , если вы находитесь в другой подсети - используйте внешний адрес
3 голосов
/ 06 июня 2011

Вы можете поместить код повторения в предложение catch для IOException

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

Примечание. Как и большинство людей говорили, это, вероятно, не очень хорошее решение для производственного выпуска, но для тестирования это, вероятно, сработает.просто отлично.

3 голосов
/ 03 июня 2011

Это не совсем то, что вы можете легко исправить в программном обеспечении.Я думаю, что правильный ответ - это исправление фильтров / конфигурации, которые направляют трафик на ваш внутренний веб-сервер, или путем правильной настройки DNS для возврата правильного IP-адреса в зависимости от того, где вы находитесь (внутри или вне сети).Дополнительную информацию можно найти здесь:

Доступ к внутреннему сетевому ресурсу с использованием внешнего IP-адреса

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

и путем поиска в Google что-то вроде "внешнего IP"не работает во внутренней сети "

3 голосов
/ 31 мая 2011

Опираясь на очень хороший комментарий от harism, я просто использовал бы статическое логическое значение для выбора IP-адреса и, таким образом, избегал пинговать неправильный 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;
1 голос
/ 04 июня 2011

Я бы поместил такую ​​информацию, специфичную для окружающей среды, в файл свойств (или, в любом случае, в какой-то файл конфигурации). Все, что вам нужно, это файл с одной строкой (очевидно, вы изменили бы IP-адрес на то, что вам нужно):

serverUrl=192.168.1.1

Java уже имеет встроенную функцию для чтения и записи файлов такого типа (см. Ссылку выше). Вы также можете сохранить информацию о подключении к базе данных и т. Д. В этом файле. Что-нибудь действительно специфичное для окружающей среды.

В вашем коде похоже, что вы используете константы для хранения URL сервера. Я бы не предложил это. Что происходит при изменении URL-адреса сервера? Вам нужно изменить и пересобрать свой код. Однако в случае файла конфигурации изменения кода не потребуются.

1 голос
/ 03 июня 2011

1-й, вы должны иметь возможность обрабатывать случай во время выполнения. Я очень настоятельно рекомендую против различных сборок .. Например: попробуйте внешнюю, если не удается внутреннюю.

Между тем немного эвристики:
Внутренний IP подразумевает, что сеть одинакова. Таким образом, вы можете проверить это, если это то же самое, попробуйте внутренний адрес 1-й, в противном случае внешний имеет приоритет. Позже сохраните сопоставление локального IP-адреса с успешно подключенным и найдите его, чтобы изменить приоритет.

Само разрешение может быть получено путем запроса корневого '/' сервера с таймаутом (вы можете использовать 2 разных потока для одновременного выполнения задачи, если вам так хочется).

Кроме того, если у вас есть доступ к маршрутизатору / брандмауэру, его можно распознать по внешним адресам и правильно обработать его. Таким образом, вы можете получить внешний адрес, который работает правильно.

1 голос
/ 31 мая 2011

Вы можете изменить свой вызов retrieve (), чтобы принимать хост в качестве параметра.При запуске попробуйте пропинговать каждый возможный хост.Сделайте простой вызов извлечения чего-то, что очень быстро возвращается (например, может быть, на тестовую страницу).Пройдите через все возможные хосты, которые вы хотите попробовать.Найдя работающий, сохраните этот хост и используйте его для всех будущих вызовов.

0 голосов
/ 31 мая 2011
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");
}

и т. Д. *

...