我怎么能在一个线程中停止块方法DatagramSocket.receive()

时间:2011-11-01 03:21:09

标签: java multithreading sockets

我在主线程中创建一个DatagramSocket,然后创建一个内部类线程来监听端口。当我关闭主线程中的DatagramSocket时,它总是遇到错误socket closed因为在内部类线程中我调用了receive()方法,并且它阻止了内部类线程。这是内部类的代码:

class ReceiveText extends Thread
{
    @Override
    public void run()
    {
        while(true)
        {
            byte[] buffer = new byte[1024];
            DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
            try {
                udpSocket.receive(dp);//blocked here
                byte[] data = dp.getData();
                String message = new String(data, 0 , dp.getLength());
                setTxtAreaShowMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

我想在关闭DatagramSocket之前停止内部类线程,但不建议使用stop()方法。我怎么能这样做?

3 个答案:

答案 0 :(得分:14)

关闭套接字,这将阻止来自阻止的receive()调用。如果首先设置一个关闭标志,那么在catch(IOException)块中,如果设置了标志,则可以安全地忽略该异常。 (你也可以在DatagramSocket上使用isClosed()方法而不是标志)

答案 1 :(得分:2)

Socket.close()可以解决问题。或者你可以使用socket.setSoTimeout(1000); setSoTimeout()方法允许您以毫秒为单位定义超时时间。例如:

//if the socket does not receive anything in 1 second, 
//it will timeout and throw a SocketTimeoutException
//you can catch the exception if you need to log, or you can ignore it
socket.setSoTimeout(1000); 
socket.receive();

这是javadoc for setSoTimeout();

默认情况下,超时为0且不确定,通过将其更改为正数,它将仅阻止您指定的数量。 (确保在调用socket.receive())

之前设置它

以下是此网站上的一个示例: set timeout for socket receive

答案 2 :(得分:1)

使用UDP,您可以从另一个线程向套接字发送数据报,从而解除对read()的阻塞。 datagran可以(取决于你的协议)包含一个'suicide'命令,或者你可以使用一个额外的'shutdown'布尔值,线程在read()返回后读取。