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.
Related
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..
How can I specify a timeout on an active java.net.Socket connection? I don't mean the timeout of .accept() that blocks the process. I'd like to set a timeout that starts to count when accept method takes a connection, until the client connection is closed/output stream is returned.
Is that possible?
yes. it is possible with socket.setSoTimeout()
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.
I'm having a problem with a library that I am using. It might be the library or it might be me using it wrong!
Basically, when I do this (Timeout in milliseconds)
_ignitedHttp.setConnectionTimeout(1); // v short
_ignitedHttp.setSocketTimeout(60000); // 60 seconds
No timeout exception is generated and it works ok, however, when I do the following,
_ignitedHttp.setConnectionTimeout(60000); // 60 seconds
_ignitedHttp.setSocketTimeout(1); // v short
I get a Socket Exception.
So, my question is why can I not simulate a Connection Exception? Am I misunderstanding the difference between a socket and a connection time-out? The library is here (not officially released yet).
A connection timeout occurs only upon starting the TCP connection. This usually happens if the remote machine does not answer. This means that the server has been shut down, you used the wrong IP/DNS name, wrong port or the network connection to the server is down.
A socket timeout is dedicated to monitor the continuous incoming data flow. If the data flow is interrupted for the specified timeout the connection is regarded as stalled/broken. Of course this only works with connections where data is received all the time.
By setting socket timeout to 1 this would require that every millisecond new data is received (assuming that you read the data block wise and the block is large enough)!
If only the incoming stream stalls for more than a millisecond you are running into a timeout.
A connection timeout is the maximum amount of time that the program is willing to wait to setup a connection to another process. You aren't getting or posting any application data at this point, just establishing the connection, itself.
A socket timeout is the timeout when waiting for individual packets. It's a common misconception that a socket timeout is the timeout to receive the full response. So if you have a socket timeout of 1 second, and a response comprised of 3 IP packets, where each response packet takes 0.9 seconds to arrive, for a total response time of 2.7 seconds, then there will be no timeout.
We are doing FTP connection through our applicaion which is a JAVA aplication.
We have set timeout for connection using Socket.connect(Adreess,timeout) method before calling FTPClient.connect() method.
During retriving files from the FTP site under same connection we havent set any timeout. Is it mandatory to call method FTPClient.setSoTimeOut(timeout) method to set individual time out for each such interaction under same connection or Socket.connect(Adreess,timeout) method will set timeout for each interaction with FTP site under one connection?
I would also like to know What is the difference between these two methods?
The timeout in Socket.connect() is connect timeout, which is the time to wait for TCP handshake to finish. This timeout only occurs once per connection.
setSoTimeout() is called socket read timeout, which is how long you wait to read pending bytes from socket. This occurs on every socket read throughout the TCP session.
It's good practice to set both timeout value so you don't rely on system defaults, which may vary. However, the timeout may not work sometimes when the call is stuck in native code. For example, the connect timeout is not honored if firewall silently drops packet.