2012-12-24 22 views
10

Ho scritto un programma che apre una connessione httpurl a un sito Web tramite proxy casuali. La mia httpurlconnection si chiama conn. Ora so, che alcune di quelle deleghe potrebbe essere troppo lento, così ho impostato il timeout della connessione a 40000 millisecondi con conn.setConnectTimeout(40000) e conn.setReadTimeout(40000).Java Timeout HTTPUrlConnection non funziona

Dopo questo modo, ho ottenuto questo codice:

long diff = 0; 
    long starttime = 0; 
    long endtime = 0; 

    try 
    { 
     starttime = System.currentTimeMillis(); 
     conn.connect(); 

     endtime = System.currentTimeMillis(); 

     diff = endtime - starttime; 

     if (endtime <= starttime + conn.getConnectTimeout()) 
     { 
      //Trying to read sourecode 
      InputStreamReader isrConn = new InputStreamReader(conn.getInputStream()); 
      BufferedReader brConn = new BufferedReader(isrConn); 

      line = brConn.readLine(); 

      while (line != null) 
      { 

       response += line + "\t"; 
       try 
       { 
        line = brConn.readLine(); 
       } catch (IOException e) 
       { 
        printError("Reading sourcecode failed."); 
       } 

      } 
     } 
     else 
     { 
      response = "blabla."; 
     } 




    // If conn.connect failed 
    } catch (IOException e) 
    { 
     endtime = System.currentTimeMillis(); 
     diff = endtime - starttime; 

     response = "Message: "+e.getMessage() +" MyTimeout:"+ conn.getConnectTimeout() +" Actual time passed: "+ diff; 
       e.printStackTrace(); 


    } 

Non ci sono ragioni per cui la connessione potrebbe fallire, così in molti casi ottengo all'ultimo catch-block e ottenere il seguente output:


Messaggio: timeout della connessione: la connessione MyTimeout: 40000 tempo effettivo passato: 21012

Messaggio: timeout della connessione: collegare MyTimeout: 40000 tempo effettivo passato: 21016

Messaggio: Timeout della connessione: la connessione MyTimeout: 40000 tempo effettivo passato: 21010

Messaggio: Timeout della connessione: collegare MyTimeout: 40000 tempo effettivo passato: 21009


Quindi la mia domanda sarebbe : Ho impostato il timeout a 40000 millisecondi, ma ottengo una risposta scaduta dopo circa 21000 millisecondi, qualcuno di voi sa perché?

EDIT: im utilizzando Windows 7 e ora ho aggiunto e.printStackTrace() al catch-block, come detto nei commenti. grazie mille l'uscita è ora (esempio):

java.net.ConnectException: Connection timed out: connect 
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) 
    at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) 
    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) 
    at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) 
    at java.net.AbstractPlainSocketImpl.connect(Unknown Source) 
    at java.net.PlainSocketImpl.connect(Unknown Source) 
    at java.net.Socket.connect(Unknown Source) 
    at sun.net.NetworkClient.doConnect(Unknown Source) 
    at sun.net.www.http.HttpClient.openServer(Unknown Source) 
    at sun.net.www.http.HttpClient$1.run(Unknown Source) 
    at sun.net.www.http.HttpClient$1.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.net.www.http.HttpClient.privilegedOpenServer(Unknown Source) 
    at sun.net.www.http.HttpClient.openServer(Unknown Source) 
    at sun.net.www.http.HttpClient.<init>(Unknown Source) 
    at sun.net.www.http.HttpClient.New(Unknown Source) 
    at sun.net.www.http.HttpClient.New(Unknown Source) 
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source) 
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) 
    at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) 
    at TestThread.getSourcePage(TestThread.java:361) 
    at TestThread.aChecker(TestThread.java:216) 
    at TestThread.getNextProxy(TestThread.java:169) 
    at TestThread.getNextC(TestThread.java:157) 
    at TestThread.aChecker(TestThread.java:273) 
    at TestThread.getNextProxy(TestThread.java:169) 
    at TestThread.aChecker(TestThread.java:295) 
    at TestThread.getNextProxy(TestThread.java:169) 
    at TestThread.getNextC(TestThread.java:157) 
    at TestThread.run(TestThread.java:103) 
    at java.lang.Thread.run(Unknown Source) 

Message: Connection timed out: connect MyTimeout:40000 Actual time passed: 21015 
+3

uscita Si prega di inviare e l'analisi dello stack effettivo invece che il proprio messaggio. –

+1

questo potrebbe essere dipendente dal sistema operativo, si prega di specificare quale sistema operativo è quello –

+0

Come menzionato da Brian Roach, si prega di postare l'output da 'e.printStackTrace()' nel blocco catch. –

risposta

6

Nella mia esperienza, HttpURLConnection non si timeout durante la risoluzione dei nomi. Se il tuo dispositivo ha memorizzato nella cache l'indirizzo di destinazione, verrà timeout correttamente.

Per scopi di test, utilizzare il proprio indirizzo IP nel codice.

Questo di solito accade a me su dispositivi mobili.

10

Guardate l'eccezione si ha:
Il più grande indizio: Stai ricevendo java.net.ConnectException Come da javadoc, java.net.ConnectException significa che la connessione è stata rifiutata da remoto per motivi quali nessun processo è in ascolto sulla porta.

public class ConnectException 
extends SocketException 

Signals that an error occurred while attempting to connect a socket to a remote address and port. 
Typically, the connection was refused remotely (e.g., no process is listening on the remote 
address/port) 

Cosa si è configurato in HttpURLConnection:
Il timeout per la connessione (dato che la porta remota accetta la connessione). Se il timeout della connessione scade, si ottiene java.net.SocketTimeoutException e non uno java.net.ConnectException.

Quindi, cosa sta causando java.net.ConnectException?
ho provato i seguenti casi di test:

+------------+------------+----------------+------------------+---------------------------------+ 
    | Valid Host | Valid Port | Valid Proxy IP | Valid Proxy Port | Exception      | 
    +------------+------------+----------------+------------------+---------------------------------+ 
#1 | yes  | yes  | -NA-   | -NA-    | -- none --      | 
#2 | yes  | no   | -NA-   | -NA-    | java.net.ConnectException  | 
    +------------+------------+----------------+------------------+---------------------------------+ 
#3 | yes  | yes  | yes   | yes    | -- none --      | 
#4 | yes  | no   | yes   | yes    | java.net.SocketTimeoutException | 
#5 | yes  | yes  | yes   | no    | java.net.ConnectException  | 
    +------------+------------+----------------+------------------+---------------------------------+ 
  • Caso # 1, # 3 sono i percorsi felici in cui tutte le configurazioni sono corrette
  • In caso # 4, otteniamo un java.net.SocketTimeoutException perché il processo java è in grado di stabilire una connessione (alla porta proxy), ma non ottiene alcun dato da leggere come numero di porta dell'host di destinazione non valido
  • Nel caso # 2, # 5 otteniamo java.net.ConnectException perché la porta in cui il processo java tenta di scrivere/read non è valido
  • Il valore di timeout della connessione non è valido per i casi in cui nessun processo è in attesa sulla porta a cui tenta di connettersi il processo java. Ecco perché si ottiene ConnectException prima timeout

Message: Connection refused: connect MyTimeout:10000 Actual time passed: 6549 java.net.ConnectException: Connection refused: connect at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) .... ....

Conclusione:

  • Alcune delle deleghe che si stavano cercando di connettersi, deve essere giù. Quindi processo java gettato java.net.ConnectException
  • E 'meglio per la cattura java.net.ConnectException e segnare il proxy come non valido/giù