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

我在主线程中创建一个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()方法。 我怎样才能做到这一点?

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

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(); 

这是setSoTimeout()的javadoc ;

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

以下是此站点上的示例: 设置套接字接收的超时

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