94 votes

Pourquoi une "java.net.ConnectException : Connection timed out" alors que l'URL est en service ?

Je reçois un ConnectException: Connection timed out avec une certaine fréquence de mon code. L'URL que j'essaie d'atteindre est en haut. Le même code fonctionne pour certains utilisateurs, mais pas pour d'autres. Il semble qu'une fois qu'un utilisateur commence à obtenir cette exception, il continue à l'obtenir.

Voici la trace de la pile :

java.net.ConnectException: Connection timed out
Caused by: java.net.ConnectException: Connection timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.Socket.connect(Socket.java:516)
    at java.net.Socket.connect(Socket.java:466)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:365)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:477)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:214)
    at sun.net.www.http.HttpClient.New(HttpClient.java:287)
    at sun.net.www.http.HttpClient.New(HttpClient.java:299)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:796)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:748)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:673)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:840)

Voici un extrait de mon code :

URLConnection urlConnection = null;
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter = null;
InputStream inputStream = null;

try {
    URL url = new URL(urlBase);
    urlConnection = url.openConnection();
    urlConnection.setDoOutput(true);

    outputStream = urlConnection.getOutputStream(); // exception occurs on this line
    outputStreamWriter = new OutputStreamWriter(outputStream);
    outputStreamWriter.write(urlString);
    outputStreamWriter.flush();
    inputStream = urlConnection.getInputStream();
    String response = IOUtils.toString(inputStream);
    return processResponse(urlString, urlBase, response);
} catch (IOException e) {
    throw new Exception("Error querying url: " + urlString, e);
} finally {
    IoUtil.close(inputStream);
    IoUtil.close(outputStreamWriter);
    IoUtil.close(outputStream);
}

7 votes

Veuillez marquer une réponse comme acceptée si vous avez résolu votre problème :)

91voto

Jumpy Points 1311

Les délais de connexion (en supposant un réseau local et plusieurs machines clientes) résultent généralement de

a) une sorte de pare-feu sur le chemin qui mange simplement les paquets sans dire à l'expéditeur des choses comme "Pas de route vers l'hôte".

b) perte de paquets due à une mauvaise configuration du réseau ou à une surcharge de la ligne

c) trop de demandes qui surchargent le serveur

d) un petit nombre de threads/processus disponibles simultanément sur le serveur, ce qui fait qu'ils sont tous pris. Cela se produit surtout avec les demandes qui prennent beaucoup de temps à exécuter et qui peuvent se combiner avec c).

J'espère que cela vous aidera.

2 votes

Ce qui m'a aidé à déboguer ce problème, c'est d'envoyer un ping au serveur auquel je faisais la demande. J'ai découvert que l'URL se résolvait sur l'IP publique, plutôt que sur l'IP privée que j'avais prévue. Un nouveau mappage dans le fichier /etc/hosts a permis de résoudre le problème. J'ajoute ce commentaire au cas où quelqu'un d'autre serait confronté à un problème similaire.

34voto

Alexander Points 4298

Si l'URL fonctionne correctement dans le navigateur Web sur la même machine, il se peut que le code Java n'utilise pas le proxy HTTP que le navigateur utilise pour se connecter à l'URL.

0 votes

Voici le lien SO - Comment activer HTTP_PROXY en java stackoverflow.com/a/120802/2413870

8voto

M Hamza Javed Points 1130

Le message d'erreur dit tout : votre connexion a expiré. Cela signifie que votre demande n'a pas reçu de réponse dans un certain délai (par défaut). La raison pour laquelle aucune réponse n'a été reçue est probablement l'une des suivantes :

a) L'IP/domaine ou le port est incorrect

b) L'IP/domaine ou le port (c'est-à-dire le service) est hors service.

c) L'IP/domaine prend plus de temps que le délai par défaut pour répondre.

d) Votre pare-feu bloque les demandes ou les réponses sur le port que vous utilisez.

e) Votre pare-feu bloque les requêtes vers cet hôte particulier.

f) Votre accès Internet est en panne

g) Votre serveur en direct est hors service, par exemple dans le cas d'un "appel rest-API".

Notez que des pare-feu et des blocages de port ou d'IP peuvent être mis en place par votre FAI.

5voto

Powerlord Points 43989

Je recommande d'augmenter le délai de connexion avant de récupérer le flux de sortie, comme ceci :

urlConnection.setConnectTimeout(1000);

Où 1000 est en millisecondes (1000 millisecondes = 1 seconde).

26 votes

Ce n'est pas l'augmenter, c'est la diminuer, radicalement. Par défaut, c'est environ une minute, et vous ne peut pas Vous ne pouvez pas l'augmenter, vous ne pouvez que l'abaisser.

4voto

  • Essayez de faire le Telnet pour voir s'il y a un problème de pare-feu.
  • effectuer tracert / traceroute pour trouver le nombre de sauts

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