简体   繁体   English

中断DatagramSocket.receive中的一个线程

[英]Interrupt a thread in DatagramSocket.receive

I'm building an application that listens on both TCP and UDP, and I've run into some trouble with my shutdown mechanism. 我正在构建一个侦听TCP和UDP的应用程序,而且我的关机机制遇到了一些问题。 When I call Thread.interrupt() on each of the listening threads, the TCP thread is interrupted from listening, whereas the UDP listener isn't. 当我在每个侦听线程上调用Thread.interrupt()时,TCP线程会被监听中断,而UDP侦听器则不会。 To be specific, the TCP thread uses ServerSocket.accept() , which simply returns (without actually connecting). 具体来说,TCP线程使用ServerSocket.accept()ServerSocket.accept()返回(没有实际连接)。 Whereas the UDP thread uses DatagramSocket.receive() , and doesn't exit that method. UDP线程使用DatagramSocket.receive() ,但不退出该方法。

Is this an issue in my JRE, my OS, or should I just switch to (Datagram)Socket.close() ? 这是我的JRE,我的操作系统中的问题,还是应该切换到(Datagram)Socket.close()

UPDATE: I've found an analysis of the problem. 更新:我发现了对问题的分析 It confirms that the behavior is not consistent. 它确认行为不一致。

A common idiom for interrupting network IO is to close the channel. 中断网络IO的常用习惯是关闭通道。 That would be a good bet if you need to effectively interrupt it while its waiting on sending or receiving. 如果您需要在等待发送或接收时有效地中断它,那将是一个不错的选择。

public class InterruptableUDPThread extends Thread{

   private final DatagramSocket socket;

   public InterruptableUDPThread(DatagramSocket socket){
      this.socket = socket;
   }
   @Override
   public void interrupt(){
     super.interrupt();  
     this.socket.close();
   }
}

As far as I know, close() is the proper way to interrupt a blocked socket. 据我所知, close()是中断被阻塞的套接字的正确方法。 Interrupting and keeping open something that may have already done a partial read or write makes things unnecessarily complex. 中断和保持可能已经完成部分读取或写入的操作会使事情变得不必要地复杂化。 It's easier to only have to deal with a "success" or "give up" result. 只需要处理“成功”或“放弃”结果就更容易了。

DatagramSocket.receive blocks until it receives a datagram. DatagramSocket.receive阻塞,直到收到数据报。 Probably what you need to do is use setSoTimeout to make it timeout. 您可能需要做的是使用setSoTimeout使其超时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM