According to the java docs of connection.setReadTimeout() -
"A non-zero value specifies the timeout when reading from Input stream when a connection is established to a resource. If the timeout expires before there is data available for read, a java.net.SocketTimeoutException is raised. A timeout of zero is interpreted as an infinite timeout."
So if I set a certain read timeout, and start downloading a file, will the download break if the timeout is reached?
Or does it break only when there is nothing to read for that specified timeout?
It's only raise exception if there is no response. It'll not break while getting data so don't worry about.
If you start downloading the file and there is no interruption, the timeout will not occur.
If you have the timeout set to 30 seconds. If you're downloading for 15 seconds and after those 15 seconds, the connection fails, you will have to wait another 30 seconds before timeout.
The read timeout starts afresh every time the recv() function is called.
So the correct answer is (2).
Related
I have made connection to the wechat api using HttpUrlConnection and set connectTimeOut to 500 milis and got the response in 3 seconds and now I decreased the connectTimeOut to 100 milis and getting the response in 2 seconds. So not able to understand the reason behind this, see the code and javadoc but not found anything related to it.
You are confused. Connection timeout is not the maximum time to read the response, it is the maximum time to create the connection. Sending the request and reading the response come afterwards.
If you got a response, clearly the connection succeeded within your timeout period, but it then took some seconds to read the response. These are not the same thing.
Possibly you may want to set a read timeout as well, or instead.
But the timeouts you're setting are ridiculously short. Three seconds for a connect timeout and ten seconds for a read timeout would be about the minimum.
I am seeing some strange issue with my automation tests.
There is a following setup:
Server: Centos 6
Client1: Windows 7
Client2: Centos 6
I'm writing the test that simulated connection disruption to server by blocking the outbound connection on server's iptables. But, the behavior of socket differs on Windows from one on Linux client.
One thing though, in both cases there is a line of Java code that does:
socket.setSoTimeout(0)
Scenario #1 (Windows):
send the ssh command to server iptables -A OUTPUT --dport XYZ -j DROP
After approximately 60 seconds my console says java.net.SocketTimeoutException: Read timed out
Connection drops
Scenario #2 (Centos)
send the same command as above
I tried waiting as much as 10 minutes but console never outputs the exception.
So, the question, is there a way to make the behavior of socket the same (or approximately the same)?
I read that Windows actually does not use SO_TIMEOUT but SO_RCVTIMEO instead.
From setSoTimeout(int timeout):
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.
Are you able to set a realistic timeout value?
After reading David's answer I observed the behavior of that socket in order to see how does it work.
As David stated, SO_TIMEOUT only applies to future read() calls and not the ones that have already been called.
The common pattern for my tests was:
Connect the user (socket)
Exchange some data
Server does not communicate with user for some time
At this point client has already entered the read method. Setting SO_TIMEOUT at this point is useless.
Block the server's OUTBOUND traffic on local port (some random 55000+ port)
Wait for SocketTimeoutException
If I was to set the SO_TIMEOUT before, my socket would throw the exceptions like mad. So, I was hoping and was wrong when excepting for exception to be thrown in case of network outage. On the contrary, exception is being throw in case of traffic outage.
Can this be an issue with Keep-Alive? My socket sets it to true.
Solution (empiric):
I measured (on Windows) that it takes approximately 60 seconds for socket to go down.
So, when I need to sever the connection, I create a thread that checks every 2 seconds if current time is greater from (creation time + 60s). When it reaches that time, it invokes socket.close which effectively causes SocketException.
This solution is by no means optimal but it will have to do, at least for now.
Hope this will be of any help to someone else out here..
I want to detect when a database is down and I know once the database is down it will throw a SQLException. Using Connection.isValid(). What does the timeout paramter represent? It says:
timeout - - The time in seconds to wait for the database operation
used to validate the connection to complete. If the timeout period
expires before the operation completes, this method returns false. A
value of 0 indicates a timeout is not applied to the database
operation.
What does this mean?
The isValid() method allows you to check the Connection for validity.
For this method you can specify a timeout in seconds, when this timeout runs out before the internal validity check is finished, the method will return false.
This is useful if you don't want your program to wait a long time in case the validity check takes too long.
If you give 0 as input for timeout, no timeout will be applied and your program will wait until the check is complete.
Well, "database is down" means it does not respond. It's not like it can just tell you "hey, I'm down". So the timeout means how long does this method wait for response, before considering database as offline.
It represent the time to discard the connection if any connection is idle for that much time.
If I set soTimeout on java sockets what will be the behaviour in case of active peer vs passive peer. For instance if I have a readtimeout value 1 minute and having a file transfer and which takes 5 minutes will it get readtimeout exception or not ? For me its necessary to get timeout exception when connection hangs.
The soTimeout setting explicitly affects operations that read from the socket's input stream. You can think of it as allowing the caller to define a timed block on read operations. From the Javadoc for setSoTimeout:
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds.
With this option set to a non-zero timeout, a read() call on the
InputStream associated with this Socket will block for only this
amount of time. If the timeout expires, a
java.net.SocketTimeoutException is raised, though the Socket is still
valid.
In the case of a passive peer, no timeout will be thrown solely due to the peer not calling read. However, if and when it does make a read call, the call must return data before the soTimeout expires, or else a SocketTimeoutException will be raised.
I trying to make a call to a very heavy duty process.
It's average work length is estimated by 9-10 minutes.
When I'm executing the process, I set the timeout for a ridiculously huge number: 99999999.
After 2 minutes, I get the following error:
java.net.SocketTimeoutException: Read timed out
I tried to mess with it some more, and I set the timeout to 3000, and after 3 seconds as anticipated I got the same error.
Do you have any idea on why socket.setSoTimeout(99999999) sets it to 120000 max?
I had the same problem and the solution was not use
socket.shutdownInput(); socket.shutDownOutput(); until the last time of reading or writing data to the socket. This made the socket go to FIN_WAIT state thus waiting 2 minutes before closing. You can read more about it in this post
Clearly you aren't setting the timeout you think you're setting, or someone else is changing it afterwards. You'll have to post some code to get further elucidation.
Note that according to W.R. Stevens in TCP/IP Illustrated, Vol II, #17.4, the timeout is held in a short as a number of 1000Hz ticks, so a timeout beyond 11 minutes isn't possible. This applies to the BSD code.
I'm not sure how your application works, but try to set an infinite timeout to the socket
public void setSoTimeout(int timeout)
throws SocketException
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.
If you provide more information about your call, i may improve the answer.