2012-12-24 15 views
10

Ich habe ein Programm geschrieben, das eine httpurlconnection zu einer Website durch zufällige Proxys öffnet. Meine httpurlconnection heißt conn. Jetzt weiß ich, dass einige dieser Proxies möglicherweise zu langsam sind, also habe ich das Timeout der Verbindung auf 40000 Millisekunden mit conn.setConnectTimeout(40000) und conn.setReadTimeout(40000) gesetzt.Java HTTPUrlConnection Timeout funktioniert nicht

Nach so tun, ich erhielt diesen Code:

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(); 


    } 

Es gibt Gründe, warum die Verbindung fehlschlagen könnte, also in vielen Fällen i bis zum letzten catch-Block erhalten und die folgende Ausgabe:


Nachricht: Connection timed out: connect MyTimeout: 40000 Tatsächliche Zeit vergangen: 21012

Nachricht: Connection timed out: connect MyTimeout: 40000 Tatsächliche Zeit vergangen: 21016

Nachricht: Connection timed out: connect MyTimeout: 40000 Tatsächliche Zeit vergangen: 21010

Nachricht: Connection timed out: connect MyTimeout: 40000 Tatsächliche Zeit vergangen: 21009


Also meine Frage wäre : Ich habe das Timeout auf 40000 Millisekunden eingestellt, aber ich bekomme eine "Connection Timeout" -Antwort nach etwa 21000 Millisekunden, weiß jemand von euch, warum das ist?

EDIT: ich benutze Windows 7 und ich habe jetzt e.printStackTrace() zum catch-block hinzugefügt, wie in den Kommentaren erzählt. Danke bis jetzt. Die Ausgabe ist jetzt (Beispiel):

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

Bitte Ausgabe und poste den tatsächlichen Stack-Trace statt Ihrer eigenen Mitteilung. –

+1

Dies könnte Betriebssystemabhängig sein, bitte geben Sie an, welches Betriebssystem das ist –

+0

Wie von Brian Roach erwähnt, posten Sie bitte die Ausgabe von 'e.printStackTrace()' im catch-Block. –

Antwort

6

Nach meiner Erfahrung, HttpUrlConnection nicht Timeout während der Namensauflösung. Wenn Ihr Gerät die Zieladresse zwischengespeichert hat, wird es korrekt ablaufen.

Für Testzwecke verwenden Sie Ihre IP-Adresse in Ihrem Code.

Das passiert mir normalerweise auf mobilen Geräten.

10

Blick auf die Ausnahme, die Sie bekam:
Der größte Hinweis: Sie erhalten java.net.ConnectException Wie pro javadoc, java.net.ConnectException bedeutet, dass die Verbindung der Ferne aus Gründen verweigert wurde, wie kein Prozess auf dem Port lauscht.

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) 

Was Sie in HttpURLConnection konfiguriert:
Der Timeout für die Verbindung (vorausgesetzt, dass der Remote-Port Verbindung akzeptiert). Wenn das Verbindungstimeout abläuft, erhalten Sie eine java.net.SocketTimeoutException und keine java.net.ConnectException.

Also, was verursacht java.net.ConnectException?
ich folgende Testfälle versucht:

+------------+------------+----------------+------------------+---------------------------------+ 
    | 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  | 
    +------------+------------+----------------+------------------+---------------------------------+ 
  • Fall # 1, # 3 die glücklichen Wege sind, in dem alle configs
  • Bei # 4 korrekt sind, erhalten wir ein java.net.SocketTimeoutException weil Java-Prozess ist in der Lage Verbindung (an dem Proxy-Port) zu etablieren, sondern als Ziel-Host-Portnummer ist
  • bei # 2, invalid # 5 wir java.net.ConnectException lesen keine Daten bekommen, weil der Hafen, in der Java-Prozess zu schreiben bekommen versucht/Lesen ist ungültig
  • Der Wert für den Verbindungszeitlimit gilt nicht für Fälle, in denen kein Prozess den Port überwacht, mit dem der Java-Prozess versucht, eine Verbindung herzustellen. Deshalb sollten Sie Connect bevor Timeout abläuft

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) .... ....

Fazit:

  • Einige der Proxies Sie eine Verbindung herstellen wollten, müssen nach unten sein. Daher Java-Prozess warf java.net.ConnectException
  • Es ist besser java.net.ConnectException zu fangen und den Proxy als ungültig markieren/ab
Verwandte Themen