Reputation: 557
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
Upvotes: 9
Views: 3136
Reputation: 1187
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();
Upvotes: 1
Reputation: 7890
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.
Upvotes: 7