92 votes

Obtention de java.net.SocketTimeoutException : La connexion a expiré dans Android

Je suis relativement nouveau dans le développement Android. Je développe une application Android dans laquelle j'envoie des requêtes au serveur web et analyse des objets JSON. J'obtiens fréquemment java.net.SocketTimeoutException: Connection timed out exception lors de la communication avec le serveur. Parfois, il fonctionne parfaitement sans aucun problème. Je sais que cette même question a été posée de nombreuses fois. Mais je n'ai toujours pas obtenu de solution satisfaisante à ce problème. Je poste mon code de communication logcat et app-server ci-dessous.

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 

Quelqu'un peut-il m'aider à trouver une solution à ce problème ? Merci d'avance....

74voto

akh Points 521

J'ai cherché sur tout le web et après avoir lu beaucoup de documents concernant l'exception de délai de connexion, la chose que j'ai comprise est que, en empêchant les SocketTimeoutException est au-delà de nos limites. Une façon de gérer efficacement ce problème est de définir un délai de connexion et de le gérer ultérieurement en utilisant une commande de type try-catch bloc. J'espère que cela aidera toute personne confrontée au même problème à l'avenir.

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

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

30voto

Makenshi Points 53

Je suis conscient que cette question est un peu ancienne. Mais comme je suis tombé dessus en faisant des recherches, j'ai pensé qu'un petit complément pourrait être utile.

Comme indiqué, l'erreur ne peut être résolue par le client, car il s'agit d'un problème lié au réseau. Cependant, ce que vous pouvez faire, c'est réessayer de vous connecter plusieurs fois. Cela peut fonctionner comme une solution de contournement jusqu'à ce que le vrai problème soit résolu.

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

Peut-être que cela aidera quelqu'un.

4voto

KishanSolanki124 Points 966

Si vous utilisez Kotlin + Retrofit + Coroutines alors utilisez simplement try y catch pour les opérations de réseau comme,

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

Où, Exception est le type de kotlin et non de java.lang

Ceci traitera chaque exception comme,

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

Voici mon usersList() fonction

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

Note : Votre classe RetrofitClient doit avoir ceci en tant que client

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

2voto

xetiro Points 112

Si vous testez le serveur en localhost, votre appareil Android doit être connecté au même réseau local. Ensuite, l'URL du serveur utilisée par votre APP doit inclure l'adresse IP de votre ordinateur et non le masque "localhost".

1voto

goku Points 113

J'ai rencontré le même problème lors de la connexion à EC2, le problème était avec le groupe de sécurité, J'ai résolu le problème en ajoutant les IPs autorisées au port 5432.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X