The Java httpurlconnection timeout does not work
I wrote a program to open the HTTP URL connection of a website through a random proxy My httpurlconnection is called Conn. now I know that some agents may be too slow, so I have set the connection timeout to 40000 milliseconds using conn.setconnecttimeout (40000) and conn.setreadtimeout (40000)
After doing so, I get this 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(); }
There are reasons why the connection may fail, so in many cases, I get the last catch block and get the following output:
Message: connection timeout: connection mytimeout: 40000 actual passing time: 21012
Message: connection timeout: connection mytimeout: 40000 actual delivery time: 21016
Message: connection timeout: connection mytimeout: 40000 actual time to pass: 21010
Message: connection timeout: connection mytimeout: 40000 actual time to pass: 21009
So my question is: I set the timeout to 40000 milliseconds, but after about 21000 milliseconds, I get a "connection timeout" - response. Do you know why?
Edit: im using Windows 7 and I now add e.printstacktrace() to the catch block, as stated in the comment Thank you so far The output is now (example):
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
Solution
Look at the exceptions you get:
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)
The timeout of the content connection you configured in httpurlconnection (the given remote port accepts the connection) If the connection timeout expires, you will get Java net. Sockettimeoutexception, not Java net. ConnectException.
So what causes Java net. ConnectException? I tried the following test cases:
+------------+------------+----------------+------------------+---------------------------------+ | 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 | +------------+------------+----------------+------------------+---------------------------------+
>Case #1, #3 is all happiness paths configured correctly > in #4 case, we get a Java net. Sockettimeoutexception, because the java process can establish a connection (to the proxy port), but no data is read, because the port number of the target host is invalid > if #2, #5, we get Java net. Connectexception, because the port that the java process is trying to write / read is invalid > connection timeout value is not applicable to the case where the port that the java process is trying to connect is not monitored by the process This is why you get connectexception before the timeout expires
Message: connection rejected: connection mytimeout: 10000 actual delivery time: 6549 Java net. Connectexception: connection rejected: connect in Java net. DualStackPlainSocketImpl. Waitforconnect (native method) in Java net. DualStackPlainSocketImpl. socketConnect(DualStackPlainSocketImpl.java:85) …. ….
Conclusion:
>Some of the agents you are trying to connect to must be turned off Therefore, the java process throws Java net. Connectexception > you'd better catch Java net. Connectexception and mark the agent as invalid / down