I get a feeling that I am missing something really obvious here.
The overall structure of my system makes me want to use a blocking DatagramChannel without Selectors, in order to keep things simple. I am trying to achieve timeout handling by setting a timeout on the socket, but this seems to have no effect.
This pseudoized code gives a hint of what I am trying to achieve.
DatagramChannel channel = DatagramChannel.open(); channel.socket().bind(some address); channel.socket().setSoTimeout(3000); channel.send(outBuffer, peerAddress); channel.receive(inBuffer);
On the other side, I have a UDP server that gives five quick responses, and then, for testing purposes, delays about five seconds before delivering the sixth response.
The delay does not trigger a SocketTimeoutException. Why is that? The timeout set on the socket does not seem to be taken into consideration when calling channel.receive.
Regards, Fredrik
Apparently the issue of not being able to timeout is not a bug with DatagramChannel, but that:
Not a bug. The read methods in SocketChannel (and DatagramChannel) do not support timeouts. If you need the timeout functionality then use the read methods of the associated Socket (or DatagramSocket) object.
Link.
This is what I did:
Interrupter
classstatic private class Interrupter implements Runnable
{
private final Thread th1;
private volatile int wait=-1;
private Interrupter(Thread ith1)
{
th1=ith1;
}
public void run()
{
while(true)
{
try{
if( wait<0 ){ th1.join(); break; }
else{ Thread.sleep(wait); th1.interrupt(); wait=-1; }
} catch(Exception e){}
}
}
}
Interrupter
Interrupter ir1=new Interrupter(Thread.currentThread());
Thread th1=new Thread(ir1);
th1.start();
// We need this so that later the wait variable
// can be passed in successfully
while( th1.getState()!=Thread.State.WAITING );
Interrupter
try{
ir1.wait=waitTimeout;
th1.interrupt();
// Receive on the socket
dc2.receive(bb2);
} catch(ClosedByInterruptException e){
// (Timed out)
Thread.interrupted();
dc2.close();
// Handle timeout here
// ...
// We need this so that later the wait variable
// can be passed in successfully
while( th1.getState()!=Thread.State.WAITING );
}
// Received packet
ir1.wait=-1;
th1.interrupt();
// We need this so that later the wait variable
// can be passed in successfully
while( th1.getState()!=Thread.State.WAITING );
Thread.interrupted();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With