socket and setSoTimeout() - java

I am quite confused about socket.setSoTimeout( int ) method.
In scenario when i call
socket.setSoTimeout(4000);
try{
string data = input.read();
}catch (InterruptedIOException e) {
}
when calling setSoTimeout() , does it pauses the sokcet and resumes after 4000 milliseconds? Or it will just completely block all reading from socket and if anything attempts to read from it while setSoTimeout is still active it will throw exception?
If the latest , why is this usefull at all? By documentation after timeout expired the exception is thrown automaticlly.
Thanks for clarification.

The key part of the documentation for Socket.setSoTimeout() is:
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.
This is saying that a read on the socket will be prevented from blocking any longer than the specified time (which is perhaps more clear when interpreted in light of the meaning of "timeout", and is certainly more clear if you are familiar with the system-level socket interface). It does not say that a read is guaranteed to block for that long, which indeed would be of questionable utility.
Among the problems solved by setting a timeout is that of handling clients that are uncleanly disconnected without closing the connection. The local machine has no way to detect that that has happened, so without a timeout, an attempt to read from a socket connected to such a client will block indefinitely.

I think,setSotimeout denotes the amount of time a server can wait for a response to read.if timeout value exceeds ,exception will be thrown.
for example.If you set setSotimeout(4000) to socket,
Socket will wait for only 4 secs for the receiver to respond,it throws exception after 4 secs.
It will be useful in slow connection networks or bad servers.
It avoids waiting for response.

Related

Stopping blocking sockets in java

I have a java socket calling a server. However, I do not know at which address I can reach the server, so I put several sockets in several threads and they try to reach the server each on one address. My probem is that I do not want to wait for the timeout but have no idea how to stop the sockets and their threads properly.
Code:
socket = new Socket();
socket.connect(endpoint, timeout); // **Blocking method**
OutputStream out = socket.getOutputStream();
//Write Data here
How can I interrupt the operation? I consider Thread.stop() a bad style and it also does not work properly. .NET Tcp Endpoints have a non-blocking pending method that allows uinsg boolean flags but I could not find something similiar
I do not know at which address I can reach the server, so I put
several sockets in several threads and they try to reach the server
each on one address.
BAD. BAD Decision. Perform some logical step to determine the server's address. Or, perform something that helps you know about the server's IP-Address.
Do this way, only if it is the last hope.
My problem is that I do not want to wait for the
timeout but have no idea how to stop the sockets and their threads
properly.
You don't have any other option that timeout. Socket.connect() is blocking. You can't do anything than waiting.
You've to wait for timeout because that is the logical way to close the socket object created. You can't just do close directly, until a timeout. Reduce the timeout to the limit when your result should come(connection should be accepted).
How can I interrupt the operation? I consider Thread.stop() a bad
style and it also does not work properly.
Yes, you should not perform Thread.stop() or Thread.interrupt(). These are bad programming styles.
If the timeout expires, make the close() operation on socket.
You should set a socket timeout for the client-socket. It is the best-practice to set a timeout for sockets. The timeout should be around 10 seconds to more depending on the needs.
You can set the timeout in your current code by calling
socket.setSoTimeout(timeout); for reading timeout, OR
for connect timeout, connect(endpoint,timeout) as you've done in your code.
If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.
You're probably not using a try-catch-finally in your code. That'd be a better design here.
As you're doing a connect timeout, so your code can be amended to exit the blocking method like as shown below :
try{
socket = new Socket();
socket.connect(endpoint,timeout); // **Blocking method**
OutputStream out = socket.getOutputStream();
//Write Data here
}
catch(Exception e){
e.printStackTrace();
}
finally{
socket.close();
}

ObjectInputStream.readObject() does not throw an exception when disconnected

I'm using a ObjectStream over a TCP connection to send data from a client to a server. Sometimtes the client is terminated while the server still waits for new data. In these cases readObject() is staying blocked without of throwing a Exception and my computation stops.
How can i determine if the ObjectStream is disconnected or only waiting for more data?
Using a timeout is difficult because of long delays between communication.
The only safe way is to use a timeout. I suspect the long delay you are seeing in detecting a disconnect is due to the nature of the network you have.
Is it really a problem if computation of a dead connection has stopped. This may waste resources for a short period but you should detect a failure within minutes and clean resources then.

Is there a way to read the inputstream for a specific amount of time?

I've a situation where a thread opens a telnet connection to a target m/c and reads the data from a program which spits out the all the data in its buffer. After all the data is flushed out, the target program prints a marker. My thread keeps looking for this marker to close the connection (successful read).
Some times, the target program does not print any marker, it keeps on dumping the data and my thread keeps on reading it (no marker is printed by the target program).
So i want to read the data only for a specific period of time (say 15 mins/configurable). Is there any way to do this at the java API level?
Use another thread to close the connection after 15 mins. Alternatively, you could check after each read if 15mins have passed and then simply stop reading and cleanup the connection, but this would only work if you're sure the remote server will continue to send data (if it doesn't the read will block indefinitely).
Generally, no. Input streams don't provide timeout functinality.
However, in your specific case, that is, reading data from a socket, yes. What you need to do is set the SO_TIMEOUT on your socket to a non-zero value (the timeout you need in millisecs). Any read operations that block for the amount of time specified will throw a SocketTimeoutException.
Watch out though, as even though your socket connection is still valid after this, continuing to read from it may bring unexpected result, as you've already half consumed your data. The easiest way to handle this is to close the connection but if you keep track of how much you've read already, you can choose to recover and continue reading.
If you're using a Java Socket for your communication, you should have a look at the setSoTimeout(int) method.
The read() operation on the socket will block only for the specified time. After that, if no information is received, a java.net.SocketTimeoutException will be raised and if treated correctly, the execution will continue.
If the server really dumps data forever, the client will never be blocked in a read operation. You might thus regularly check (between reads) if the current time minus the start time has exceeded your configurable delay, and stop reading if it has.
If the client can be blocked in a synchronous read, waiting for the server to output something, then you might use a SocketChannel, and start a timer thread that interrupts the main reading thread, or shuts down its input, or closes the channel.

Is setting a timeout on ObjectInputStream.readObject() safe?

I have an ObjectInputStream connected to an ObjectOutputStream through a socket, and I've been using Socket.setSoTimeout() to make ObjectInputStream.readObject() only block for 100ms. Since I started doing this I've been getting alot of StreamCorruptedError's while calling readObject(). Could the timeout be to blame?
I have a thread constantly getting new data through this function but I want to be able to stop it by setting a boolean to false. The thread has to keep polling the boolean and can't if it's blocked by readObject()
You can use Thread.interrupt to let it throw an InterruptedException, or in this case an InterruptedIOException. Make sure you don't swallow exceptions!
If you set the timeout shorter than the normal delays which might occur in reading a stream, you can expect the timeout to be in effect when the stream is still properly active.
100 ms seems like a long time, but not if there's disk or network traffic involved. Try timing out on something ridiculous, like a second.

Handling network timeouts in Java

i have a java program connect to server through xot protocol.
My lib i use can handle connect timeout, but there is no method like setSoTimeout() to handle timeout when send & recv data.
so, anyone could suggest me some solution for this problem.
thanks
Quan
One option is to spawn a thread to do the writing and join(timeout) it. Likewise with reading from the connection. Obviously kill the thread (and treat the connection as in an indeterminate state) when the timeout expires (as opposed to the thread dieing).
'Socket.setSoTimeout()' should apply to recv as well. See its javadoc.
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.

Categories