Java.net.SocketTimeoutException abrufen: Zeitüberschreitung der Verbindung in Android

77

Ich bin relativ neu in der Android-Entwicklung. Ich entwickle eine Android-Anwendung, in der ich eine Anfrage an den Webserver sende und JSON-Objekte analysiere. Häufig erhalte ich java.net.SocketTimeoutException: Connection timed outbei der Kommunikation mit dem Server eine Ausnahme. Manchmal funktioniert es problemlos. Ich weiß, dass dieselbe Frage so oft gestellt wurde. Trotzdem habe ich keine zufriedenstellende Lösung für dieses Problem gefunden. Ich poste unten meinen Logcat- und App-Server-Kommunikationscode.

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 

Kann mir jemand helfen, eine Lösung dafür zu finden? Danke im Voraus....

akh
quelle
1
Ich denke, das ist Ihr Netzwerkproblem
Pragnani
1
Ich habe dies auf einem Hispeed-WLAN getestet ... dies kommt immer noch häufig vor ...
akh
1
@akh: Stellen Sie sicher, dass Sie die richtige Webservice-URL verwenden, um eine httppost-Anfrage zu stellen, oder der Server läuft
ρяσsρєя K
1
@akh Es geht nicht um die Geschwindigkeit der Verbindung, aber es ist wegen der Antwort vom Server, versuchen Sie, die gleiche URL aus dem Browserfenster aufzurufen und zu überprüfen, wie viel Zeit es dauern wird ..
Pragnani
2
@Raghunandan Durch das Festlegen eines Verbindungszeitlimits wird ein Problem mit dem Verbindungszeitlimit nicht behoben.
Marquis von Lorne

Antworten:

65

Ich habe im gesamten Web gesucht und nachdem ich viele Dokumente zu Ausnahmebedingungen für das Verbindungszeitlimit gelesen habe, habe ich verstanden, dass die Verhinderung von SocketTimeoutException über unserer Grenze liegt ... Eine Möglichkeit, dies effektiv zu handhaben, besteht darin, ein Verbindungszeitlimit und eine spätere Behandlung zu definieren Ich hoffe, dies hilft jedem, der in Zukunft mit dem gleichen Problem konfrontiert ist.

HttpUrlConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(7000); //set the timeout in milliseconds
akh
quelle
26
Das Ändern des Timeout-Zeitraums bedeutet keine "Behandlung". Das Abfangen der Ausnahme funktioniert, aber das haben Sie bereits getan. Nichts davon löst tatsächlich das Problem, bei dem es sich um ein Problem mit der Netzwerkkonnektivität und überhaupt nicht um ein Programmierproblem handelt.
Marquis von Lorne
5
Ich bin damit einverstanden, dass dies ein 100% iges Netzwerkproblem ist, kein Programmierproblem ... Mit "Handhabung" meine ich, die App vor einem Absturz zu retten ... Alles, was ich möchte, ist, aus der App herauszukommen, wenn dies passiert ..... .und in Bezug auf das Abfangen der Ausnahme habe ich früher die SocketTimeoutException nicht abgefangen ... Also fange ich diese Ausnahme ab und komme aus der App heraus.
Akh
Meine Verbindungszeit & readTimeOut ist auf " 20 * 1000SocketTimeOutException" eingestellt.
Muhammad Babar
1
@MuhammadBabar Es bedeutet, dass das Netzwerk ein Problem hat, dass nach 20 Sekunden keine Antwort eingegangen ist. Sie müssen die SocketTimeoutException abfangen und die Situation entsprechend behandeln.
Akh
1
Ich verwende Retrofit. Ich setze einen okhttp-Client und setze wie OkHttpClient okHttpClient = new OkHttpClient (). newBuilder () .connectTimeout (20, TimeUnit.SECONDS) .readTimeout (20, TimeUnit.SECONDS) .writeTimeout (20, TimeUit ) .bauen(); bekomme ich immer noch das gleiche Problem?
Prasad
28

Mir ist bewusst, dass diese Frage etwas alt ist. Aber da ich bei meinen Recherchen darauf gestoßen bin, dachte ich, eine kleine Ergänzung könnte hilfreich sein.

Wie bereits erwähnt, kann der Fehler vom Client nicht behoben werden, da es sich um ein Netzwerkproblem handelt. Sie können jedoch versuchen, die Verbindung einige Male erneut herzustellen. Dies kann als Problemumgehung dienen, bis das eigentliche Problem behoben ist.

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

Vielleicht hilft das jemandem.

Makenshi
quelle
3

Wenn Sie den Server in localhost testen, muss Ihr Android-Gerät mit demselben lokalen Netzwerk verbunden sein. Dann muss die von Ihrer APP verwendete Server-URL die IP-Adresse Ihres Computers und nicht die Maske "localhost" enthalten.

Xetiro
quelle
3

Wenn Sie Kotlin + Retrofit + Coroutines verwenden, verwenden Sie einfach tryund catchfür Netzwerkoperationen wie:

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

Wo, Ausnahme ist Art von kotlinund nicht vonjava.lang

Dies behandelt jede Ausnahme wie:

  1. HttpException
  2. SocketTimeoutException
  3. FATAL EXCEPTION: DefaultDispatcher etc.

Hier ist meine usersList()Funktion

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

Hinweis: Ihre RetrofitClient-Klassen müssen dies als habenclient

OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
Kishan Solanki
quelle
1

Ich hatte dieses Problem und die Lösung bestand darin, mein Modem (Router) neu zu starten. Danach könnte ich eine Verbindung für meine App zum Internet herstellen.

Ich denke, die Bibliothek, die ich benutze, verwaltet Verbindungen nicht richtig, weil sie nur wenige Male passiert.

jan4co
quelle
1

Legen Sie dies im OkHttpClient.Builder () -Objekt fest

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

Ich habe den gleichen Fehler erhalten, als ich versehentlich die Reihenfolge der Anweisungen geändert habe

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

Nach dem Ändern der Reihenfolge von writeTimeout und readTimeout wurde der Fehler behoben. Der endgültige Code, den ich verwendet habe, ist unten angegeben:

OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .build();
Jack
quelle
4
Das Ändern der Reihenfolge sollte keinen Unterschied gemacht haben, da nur interne Felder festgelegt und dann das Objekt erstellt werden.
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();
        }
    }
}
Almaapo
quelle