it-swarm.it

Perché si verifica un'eccezione "Java.net.ConnectException: Connection scaduta" quando l'URL è attivo?

Ricevo un ConnectException: Connection timed out con una certa frequenza dal mio codice. L'URL che sto cercando di colpire è scaduto. Lo stesso codice funziona per alcuni utenti, ma non per altri. Sembra che quando un utente inizia a ricevere questa eccezione, continua ad avere l'eccezione.

Ecco la traccia dello stack:

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)

Ecco uno snippet dal mio codice:

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);
}
79
Sarah Haskins

I timeout di connessione (presupponendo una rete locale e diverse macchine client) derivano in genere da

a) una specie di firewall sulla via che semplicemente mangia i pacchetti senza dire al mittente cose come "No Route to Host"

b) perdita di pacchetti dovuta a configurazione di rete errata o sovraccarico di linea

c) troppe richieste che sovraccaricano il server

d) un piccolo numero di thread/processi disponibili simultaneamente sul server che porta a tutti loro essere presi. Ciò accade soprattutto con richieste che richiedono molto tempo per essere eseguite e possono combinarsi con c).

Spero che questo ti aiuti.

77
Jumpy

Se l'URL funziona correttamente nel browser Web sulla stessa macchina, è possibile che il codice Java non stia utilizzando il proxy HTTP utilizzato dal browser per la connessione all'URL.

29
Alexander

Ti consiglio di aumentare il timeout della connessione prima di ottenere il flusso di output, in questo modo:

urlConnection.setConnectTimeout(1000);

Dove 1000 è in millisecondi (1000 millisecondi = 1 secondo).

5
Powerlord

Il messaggio di errore dice tutto: la tua connessione è scaduta. Ciò significa che la tua richiesta non ha ricevuto una risposta entro un certo lasso di tempo (predefinito). Le ragioni per cui non è stata ricevuta alcuna risposta è probabile che sia una delle seguenti:

a) IP/dominio o porta non sono corretti

b) L'IP/dominio o porta (servizio i.e) non funziona

c) L'IP/dominio impiega più tempo del timeout predefinito per rispondere

d) Hai un firewall che blocca richieste o risposte su qualunque porta tu stia utilizzando

e) Hai un firewall che blocca le richieste a quel particolare host

f) L'accesso a Internet non funziona

g) Il tuo live-server è inattivo in caso di "rest-API call".

Nota che firewall, porte o IP possono essere installati dal tuo ISP

4
M Hamza Javed
  • prova a fare il Telnet per vedere qualsiasi problema con il firewall
  • eseguire tracert/traceroute per trovare il numero di hop
3
shahbaz sikander

Ho risolto il mio problema con:

System.setProperty("https.proxyHost", "myProxy");
System.setProperty("https.proxyPort", "80");

o http.proxyHost...

2
NikNik

Questo può essere un problema IPv6 (l'host pubblica un indirizzo IPA6 AAAA e l'host dell'utente pensa di essere configurato per IPv6 ma in realtà non è collegato correttamente). Questo può anche essere un problema MTU di rete, un blocco firewall o l'host di destinazione potrebbe pubblicare diversi indirizzi IP (casualmente o in base al Paese dei mittenti) che non sono tutti raggiungibili. O problemi di rete simili.

Non puoi fare molto oltre a impostare un timeout e aggiungere buoni messaggi di errore (specialmente stampando l'indirizzo risolto degli host). Se vuoi renderlo più robusto, aggiungi tentativi, prova parallela di tutti gli indirizzi e guarda anche nella cache di risoluzione dei nomi (positiva e negativa) sulla piattaforma Java.

1
eckes

Esiste la possibilità che il tuo IP/Host siano bloccati dall'Host remoto, specialmente se pensa che tu stia colpendo troppo.

0
larsivi

Il motivo per cui questo mi è successo è che un server remoto permetteva solo determinati indirizzi IP ma non i suoi, e stavo cercando di renderizzare le immagini dagli URL del server ... quindi tutto si fermerebbe semplicemente, mostrando l'errore di timeout che aveva... 

Assicurati che il server stia consentendo il proprio IP o che tu stia eseguendo il rendering da qualche URL remoto effettivamente esistente.

0
Damir Olejar