Подтвердить что ты не робот

Android UnknownHostException: есть ли способ установить тайм-аут?

Когда я подключаюсь к своему вебсервису для получения данных, телефон иногда отключается, DNS перепутался и т.д. Затем я получаю UnknownHostException, который отлично подходит.

Что я хочу сделать, так это установить тайм-аут при поиске имени узла здесь:

 response = httpclient.execute(httpget);

Я уже установил:

HttpConnectionParams.setConnectionTimeout(httpParameters,timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

но они, похоже, не применяются для HostLookUp. Есть ли способ установить тайм-аут при поиске узла?

Edit
Я просто обнаружил, что пользователь не может изменить тайм-аут nslookup в этом сообщении в списке рассылки hc-dev.

Мне придется вручную выставить исключение таймаута из таймера в этой точке.

4b9b3361

Ответ 1

Прежде всего HttpParams httpParams = new BasicHttpParams() лишен, используйте этот HttpURLConnection conn = (HttpURLConnection) url.openConnection();

когда размер ваших параметров превышает 2 МБ, тогда сервер дает ответ времени.

Проверьте размер своего параметра и сообщите мне.

Ответ 2

Попробуйте это

public class MyAsync extends AsyncTask<String, Integer, String> {


@Override
protected String doInBackground(String... arg0) {
     HttpParams httpParameters = new BasicHttpParams();
        // Set the timeout in milliseconds until a connection is established.
        int timeoutConnection = 3000;
        HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
        // Set the default socket timeout (SO_TIMEOUT) 
        // in milliseconds which is the timeout for waiting for data.
        int timeoutSocket = 5000;
        HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
    HttpClient client=new DefaultHttpClient(httpParameters);
    HttpGet get=new HttpGet(arg0[0]);
    try {
        HttpResponse response=client.execute(get);
        HttpEntity ent=response.getEntity();
        String res=EntityUtils.toString(ent);
        Log.d("Nzm", res);

    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

}

Ответ 3

Я нахожу Volley (я бы сказал, замена библиотеки AsyncTask) проще в использовании, а также дает меньше ошибок. Если вы используете залп, вам легче управлять таймаутами. Однако, в отношении вашего вопроса,

  response = httpclient.execute(httpget);

с этим я предположил, что вы используете AsyncTask. В httpconnection есть опция settimeout(), но это не работает должным образом из-за проблемы с DNS. Поэтому попробуйте использовать runnable() и установите для него. Я использовал этот подход в одном из моих проектов, назад, когда еще не использовал Volley.

Надеюсь, что это поможет.

Ответ 4

DefaultHttpClient client = new DefaultHttpClient();

    HttpParams httpParameters = new BasicHttpParams();
    // Set the timeout in milliseconds until a connection is established.
    // The default value is zero, that means the timeout is not used. 
    int timeoutConnection = 30000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
//      HttpConnectionParams.setHeader("Accept", "application/json");

    // Set the default socket timeout (SO_TIMEOUT) 
    // in milliseconds which is the timeout for waiting for data.
    int timeoutSocket = 30000;
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

    client.setParams(httpParameters);

Ответ 5

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

В этом методе почтовые коды связи записываются в обработчик. Мы можем вызвать этот обработчик, отправив сообщение (мы также можем передавать данные через сообщения). Записывающие операторы записываются в таймер обратного отсчета и после кодов связи в потоке. И необходимый код записывается в обработчик, чтобы отключить больше триггеров (путем назначения нового пустого обработчика объекту). Так что работает только один из запусков.

Если вам нравится эта логика и требуется больше объяснений. Пожалуйста, прокомментируйте ниже

Ответ 6

Вы можете попробовать что-то вроде: -

URLConnection connection = null;
connection =  address.openConnection();
post = (HttpsURLConnection) connection;
post.setSSLSocketFactory(context.getSocketFactory()); 
post.setDoInput(true);
post.setDoOutput(true);

// Connecting to a server will fail with a SocketTimeoutException if the timeout     elapses before a connection is established
post.setConnectTimeout(Const.CONNECTION_TIMEOUT_DELAY);
post.setRequestMethod("POST");  // throws ProtocolException


post.setRequestProperty("soapaction","");
post.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
post.setRequestProperty("Authorization", "Basic " +         Base64.encodeToString(strCredentials.getBytes(), Base64.NO_WRAP));
            post.setRequestProperty("Content-Length",           String.valueOf(requestEnvelope.length()));

//Чтение завершится с ошибкой SocketTimeoutException, если истечет время ожидания до того, как данные станут доступными. post.setReadTimeout(Const.READ_TIMEOUT_DELAY);

Ответ 7

Для меня тайм-аут не использовался, если мы потеряли соединение (чтобы проверить: выключить WiFi). Поэтому я написал метод, который пытается загрузить файл до X раз, ожидая Y миллисекунд между каждой попыткой:

public static byte[] getByteArrayFromURL(String url, int maxTries, int intervalBetweenTries) throws IOException {

    try {

        return Utils.getByteArrayFromURL(url);
    }
    catch(FileNotFoundException e) { throw e; }
    catch(IOException e) {

        if(maxTries > 0) {

            try {
                Thread.sleep(intervalBetweenTries);
                return getByteArrayFromURL(url, maxTries - 1, intervalBetweenTries);
            }
            catch (InterruptedException e1) {

                return getByteArrayFromURL(url, maxTries -1, intervalBetweenTries);
            }
        }
        else {

            throw e;
        }
    }
}

Вот метод, который загружает файл и выбрасывает UnknownHostException:

public static byte[] getByteArrayFromURL(String urlString) throws IOException {

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    InputStream in = null;
    try {

        in = new URL(urlString).openStream();
        byte[] byteChunk = new byte[BUFFER_SIZE];
        int n;

        while ((n = in.read(byteChunk)) > 0) {
            out.write(byteChunk, 0, n);
        }
    }
    finally {
        if (in != null) {
            try { in.close(); }
            catch (IOException e) { e.printStackTrace(); }
        }
    }

    return out.toByteArray();
}

Теперь, если файл, который вы хотите загрузить, не существует, метод будет немедленно сбой, иначе, если будет выведено исключение IOException (например, UnknownHostException), он будет повторять попытку до "maxTries", ожидая "intervalBetweenTries", между каждой попыткой.

Конечно, вы должны использовать это асинхронно.

Ответ 8

Попробуйте это, возможно, это будет полезно для вас.

final HttpParams httpParams = new BasicHttpParams()


HttpConnectionParams.setConnectionTimeout(httpParams, 1000)


HttpConnectionParams.setSoTimeout(httpParams, 30000) 

HttpClient hc = new DefaultHttpClient(httpParams)

try
 {


 HttpGet get = new HttpGet("http://www.google.com")

  HttpResponse response = hc.execute(get)

  take your response now.

}

Ответ 9

Вы должны использовать что-то вроде этого:

/**
 * Check availability of web service
 * 
 * @param host Address of host
 * @param seconds Timeout in seconds
 * @return Availability of host
 */
public static boolean checkIfURLExists(String host, int seconds)
{
    HttpURLConnection httpUrlConn;
    try
    {
        httpUrlConn = (HttpURLConnection) new URL(host).openConnection();

        // Set timeouts in milliseconds
        httpUrlConn.setConnectTimeout(seconds * 1000);
        httpUrlConn.setReadTimeout(seconds * 1000);

        // Print HTTP status code/message for your information.
        System.out.println("Response Code: " + httpUrlConn.getResponseCode());
        System.out.println("Response Message: "
                + httpUrlConn.getResponseMessage());

        return (httpUrlConn.getResponseCode() == HttpURLConnection.HTTP_OK);
    }
    catch (Exception e)
    {
        System.out.println("Error: " + e.getMessage());
        return false;
    }
}

Ответ 11

да, вы можете установить тайм-аут, выполните следующие шаги.

  • перейдите в eclipse window- > preferences- > Android- > DDMS и увеличьте время соединения ADB.

Ответ 12

Вы можете отправить запрос ping на ваш сервер и установить тайм-аут для запроса ping. Если true, у вас есть интернет-соединение, если false ничего не делает. Код должен выглядеть следующим образом:

public static boolean connection() throws UnknownHostException, IOException {
    String ipAddress = "94.103.35.164";
    InetAddress inet = InetAddress.getByName(ipAddress);

    if(inet.isReachable(1000)){
        return true;
    }
    else {
        return false;
    }
}

Вы можете изменить время ожидания в этом примере. Я установил 1-й тайм-аут.