我觉得我错过了一些非常明显的东西。
我的系统的整体结构使我想要使用没有选择器的阻塞DatagramChannel,以保持简单。 我试图通过在套接字上设置超时来实现超时处理,但这似乎没有效果。
这个伪化代码给出了我想要实现的内容的提示。
DatagramChannel channel = DatagramChannel.open(); channel.socket().bind(some address); channel.socket().setSoTimeout(3000); channel.send(outBuffer, peerAddress); channel.receive(inBuffer);
另一方面,我有一个UDP服务器,它提供五个快速响应,然后,为了测试目的,在发送第六个响应之前延迟大约五秒钟。
延迟不会触发SocketTimeoutException。这是为什么?调用channel.receive时,似乎没有考虑套接字上设置的超时。
此致 弗雷德里克
答案 0 :(得分:5)
显然,无法超时的问题不是DatagramChannel的错误,而是:
不是错误。 SocketChannel(和DatagramChannel)中的read方法没有 支持超时。如果您需要超时功能,请使用read 关联的Socket(或DatagramSocket)对象的方法。
答案 1 :(得分:1)
这就是我所做的:
Interrupter
类static 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();