8

我有一种感觉,我在这里遗漏了一些非常明显的东西。

我的系统的整体结构让我想使用没有选择器的阻塞 DatagramChannel,以保持简单。我试图通过在套接字上设置超时来实现超时处理,但这似乎没有效果。

这个伪代码暗示了我想要实现的目标。

DatagramChannel 通道 = DatagramChannel.open();
channel.socket().bind(一些地址);
通道.socket().setSoTimeout(3000);
channel.send(outBuffer, peerAddress);

通道.receive(inBuffer);

另一方面,我有一个 UDP 服务器,它提供五个快速响应,然后,出于测试目的,在提供第六个响应之前延迟大约五秒钟。

延迟不会触发 SocketTimeoutException。这是为什么?调用 channel.receive 时似乎没有考虑到套接字上设置的超时。

问候,弗雷德里克

4

2 回答 2

7

显然,无法超时的问题不是 DatagramChannel 的错误,而是:

不是错误。SocketChannel(和 DatagramChannel)中的读取方法不支持超时。如果您需要超时功能,请使用相关 Socket(或 DatagramSocket)对象的读取方法。

关联。

于 2013-10-14T21:08:00.820 回答
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();
于 2013-12-28T12:41:56.890 回答