Отримання java.net.SocketTimeoutException: Час очікування підключення в android


79

Я відносно новачок у розробці Android. Я розробляю додаток для Android, де я надсилаю запити на веб-сервер та аналізую об’єкти JSON. Часто я отримую java.net.SocketTimeoutException: Connection timed outвиняток під час спілкування з сервером. Інколи це спрацює без проблем. Я знаю, що це саме запитання задавали ТАК багато разів. Але все-таки я не отримав жодного задовільного рішення цієї проблеми. Я публікую нижче свій код зв’язку logcat та сервера додатків.

public JSONObject RequestWithHttpUrlConn(String _url, String param){

    HttpURLConnection con = null;
    URL url;
    String response = "";
    Scanner inStream = null;
    PrintWriter out = null;
    try {
        url = new URL(_url);
        con = (HttpURLConnection) url.openConnection();
        con.setDoOutput(true);
        con.setRequestMethod("POST");
        if(param != null){
            con.setFixedLengthStreamingMode(param.getBytes().length);
        }
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        out = new PrintWriter(con.getOutputStream());
        if(param != null){
            out.print(param);
        }
        out.flush();
        out.close();
        inStream = new Scanner(con.getInputStream());

        while(inStream.hasNextLine()){
            response+=(inStream.nextLine());
        }
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally{
        if(con != null){
            con.disconnect();
        }if(inStream != null){
            inStream.close();
        }if(out != null){
            out.flush();
            out.close();
        }
    }
}

Logcat:

03-25 10:55:32.613: W/System.err(18868): java.net.SocketTimeoutException: Connection 
timed out
03-25 10:55:32.617: W/System.err(18868):at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method)
03-25 10:55:32.617: W/System.err(18868):at dalvik.system.BlockGuard
$WrappedNetworkSystem.connect(BlockGuard.java:357)
03-25 10:55:32.617: W/System.err(18868):at 
org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:204)
03-25 10:55:32.617: W/System.err(18868):at 
org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:437)
03-25 10:55:32.617: W/System.err(18868):at        java.net.Socket.connect(Socket.java:1002)
03-25 10:55:32.621: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>
(HttpConnection.java:75)
03-25 10:55:32.621: W/System.err(18868): at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>
(HttpConnection.java:48)03-25 10:55:32.624: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection$Address.connect
(HttpConnection.java:322)03-25 10:55:32.624: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionPool.get
(HttpConnectionPool.java:89)03-25 10:55:32.628: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getHttpCon
nection(HttpURLConnectionImpl.java:285)
03-25 10:55:32.628: W/System.err(18868):at     org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.makeConn
ection(HttpURLConnectionImpl.java:267)
03-25 10:55:32.636: W/System.err(18868):at
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.connect
(HttpURLConnectionImpl.java:205)
03-25 10:55:32.636: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getOutputS
tream(HttpURLConnectionImpl.java:614)
03-25 10:55:32.636: W/System.err(18868):at 
com.myapp.core.JSONRequest.RequestWithHttpUrlConn(JSONRequest.java:63)
03-25 10:55:32.636: W/System.err(18868):    at com.myapp.core.DetailPage
$AsyncRecBooks.doInBackground(AKBookDetailView.java:265)
03-25 10:55:32.640: W/System.err(18868):    at com.myapp.core.DetailPage
$AsyncRecBooks.doInBackground(AKBookDetailView.java:1)
03-25 10:55:32.640: W/System.err(18868):    at android.os.AsyncTask$2.call
(AsyncTask.java:185)
03-25 10:55:32.640: W/System.err(18868):    at java.util.concurrent.FutureTask
$Sync.innerRun(FutureTask.java:306)
03-25 10:55:32.640: W/System.err(18868):    at java.util.concurrent.FutureTask.run
(FutureTask.java:138)
03-25 10:55:32.640: W/System.err(18868):    at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
03-25 10:55:32.648: W/System.err(18868):    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
03-25 10:55:32.648: W/System.err(18868):    at java.lang.Thread.run(Thread.java:1019)
03-25 10:55:32.652: E/JSON Parser(18868): Error parsing data org.json.JSONException:  
End of input at character 0 of 

Хто-небудь може допомогти мені, щоб знайти рішення для цього? Спасибі заздалегідь....


1
Я думаю, що це ваша проблема з мережею
Праньяні

1
Я тестував це на швидкісному wi-fi ... все-таки це трапляється часто ...
ах

1
@akh: переконайтеся, що ви використовуєте правильну URL-адресу веб-служби для надсилання запиту httppost або працює сервер
ρяσѕρєя K

1
@akh Справа не в швидкості з'єднання, але саме через відповідь сервера, спробуйте зателефонувати тій самій URL-
адресі

2
@Raghunandan Встановлення часу очікування з’єднання не вирішить проблему з часом очікування з’єднання.
user207421

Відповіді:


66

Я шукав по всьому Інтернету, і після прочитання багатьох документів щодо виключення часу очікування з’єднання зрозумів, що запобігання SocketTimeoutExceptionперевищує наші межі. Одним із способів ефективно обробляти його - визначити час очікування з’єднання, а потім обробити його за допомогою try-catchблоку. Сподіваюся, це допоможе в майбутньому тим, хто стикається з такою ж проблемою.

HttpUrlConnection conn = (HttpURLConnection) url.openConnection();

//set the timeout in milliseconds
conn.setConnectTimeout(7000);

29
Зміна періоду очікування не означає "обробку". Вловлювання винятку робить, але ви вже робили це. Жодне з цього насправді не вирішує проблему, яка є проблемою мережевого підключення, а не проблемою програмування.
user207421

5
я згоден, що це 100% проблема мережі, а не проблема програмування ... Під "обробкою" я маю на увазі врятувати програму від збою ... Все, що я хочу, - це вийти з програми, коли це станеться ..... .а щодо лову винятку, раніше я не ловив SocketTimeoutException ... Тож я ловлю цей виняток і виходжу з програми.
ах

Для мого часу підключення & readTimeOut встановлено значення 20 * 1000, як і раніше отримую SocketTimeOutException!
Мухаммед Бабар

1
@MuhammadBabar Це означає, що у мережі є якась проблема, через 20 секунд відповідь не надійшла. Вам потрібно вловити SocketTimeoutException і впоратися з ситуацією належним чином.
ах

1
я використовую модернізацію, я встановлюю клієнт okhttp і встановлюю як OkHttpClient okHttpClient = new OkHttpClient (). newBuilder () .connectTimeout (20, TimeUnit.SECONDS) .readTimeout (20, TimeUnit.SECONDS) .writeTimeout (20, TimeUnit.SONDS ) .build (); все ще я отримую те саме питання?
Прасад

29

Я усвідомлюю, що це питання трохи застаріле. Але оскільки я натрапив на це під час дослідження, я подумав, що невелике доповнення може бути корисним.

Як зазначено, помилку не може вирішити клієнт, оскільки це проблема, пов’язана з мережею. Однак ви можете повторити спробу підключення кілька разів. Це може працювати як обхідний шлях, поки не буде вирішено справжню проблему.

for (int retries = 0; retries < 3; retries++) {
    try {
        final HttpClient client = createHttpClientWithDefaultSocketFactory(null, null);
        final HttpResponse response = client.execute(get);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != 200) {
            throw new IllegalStateException("GET Request on '" + get.getURI().toString() + "' resulted in " + statusCode);
        } else {                
            return response.getEntity();
        }
    } catch (final java.net.SocketTimeoutException e) {
        // connection timed out...let's try again                
    }
}

Можливо, це комусь допомагає.


3

Якщо ви тестуєте сервер у localhost, ваш пристрій Android повинен бути підключений до тієї ж локальної мережі. Тоді URL-адреса сервера, що використовується вашим додатком, повинна містити IP-адресу вашого комп'ютера, а не маску "localhost".


3

Якщо ви використовуєте Kotlin + Retrofit + Coroutines, тоді просто використовуйте tryта catchдля мережевих операцій, таких як,

viewModelScope.launch(Dispatchers.IO) {
        try {
            val userListResponseModel = apiEndPointsInterface.usersList()
            returnusersList(userListResponseModel)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

Де, виняток - це тип, kotlinа не зjava.lang

Це буде обробляти кожен виняток, наприклад,

  1. HttpException
  2. SocketTimeoutException
  3. ФАТАЛЬНИЙ ВИНЯТК: Диспетчер за замовчуванням тощо

Ось моя usersList()функція

@GET(AppConstants.APIEndPoints.HOME_CONTENT)
suspend fun usersList(): UserListResponseModel

Примітка: Ваші класи RetrofitClient повинні мати це якclient

OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)

1

Я стикався з цією проблемою, і рішенням було перезапустити модем (маршрутизатор). Після цього я міг отримати зв’язок свого додатка з Інтернетом.

Я думаю, що бібліотека, якою я користуюся, не працює належним чином з підключеннями, оскільки це траплялося лише кілька разів.


1

Встановіть це в об’єкті OkHttpClient.Builder ()

val httpClient = OkHttpClient.Builder()
        httpClient.connectTimeout(5, TimeUnit.MINUTES) // connect timeout
            .writeTimeout(5, TimeUnit.MINUTES) // write timeout
            .readTimeout(5, TimeUnit.MINUTES) // read timeout

-1

Я отримав ту саму помилку, оскільки помилково змінив порядок висловлювань

OkHttpClient okHttpClient = new OkHttpClient().newBuilder() .connectTimeout(20, TimeUnit.SECONDS).readTimeout(20,TimeUnit.SECONDS).writeTimeout(20, TimeUnit.SECONDS) .build();

Після зміни порядку writeTimeout і readTimeout помилка вирішена. Остаточний код, який я використав, поданий нижче:

OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .build();

4
Зміна порядку не мала мати значення, оскільки все, що він робить, це встановлення внутрішніх полів, а потім побудова об’єкта.
dvallejo

-4
public JSONObject RequestWithHttpUrlConn(String _url, String param){

    HttpURLConnection con = null;
    URL url;
    String response = "";
    Scanner inStream = null;
    PrintWriter out = null;
    try {
        url = new URL(_url);
        con = (HttpURLConnection) url.openConnection();
        con.setDoOutput(true);
        con.setRequestMethod("POST");
        if(param != null){
            con.setFixedLengthStreamingMode(param.getBytes().length);
        }
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        out = new PrintWriter(con.getOutputStream());
        if(param != null){
            out.print(param);
        }
        out.flush();
        out.close();
        inStream = new Scanner(con.getInputStream());

        while(inStream.hasNextLine()){
            response+=(inStream.nextLine());
        }
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally{
        if(con != null){
            con.disconnect();
        }if(inStream != null){
            inStream.close();
        }if(out != null){
            out.flush();
            out.close();
        }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.