Прерывать поток в DatagramSocket.receive

Я создаю приложение, которое слушает как TCP, так и UDP, и я столкнулся с некоторыми проблемами с моим механизмом отключения. Когда я вызываю Thread.interrupt() в каждом из потоков прослушивания, поток TCP прерывается от прослушивания, тогда как прослушиватель UDP - нет. Чтобы быть конкретным, поток TCP использует ServerSocket.accept(), который просто возвращает (без фактического подключения). В то время как поток UDP использует DatagramSocket.receive() и не выходит из этого метода.

Является ли это проблемой в моей JRE, моей ОС или мне просто нужно перейти на (Datagram)Socket.close()?

UPDATE: я нашел анализ проблемы. Он подтверждает, что поведение несовместимо.

Ответы

Ответ 1

Общей идиомой прерывания IO сети является закрытие канала. Это будет хорошей ставкой, если вам нужно эффективно прервать его, пока он ждет при отправке или получении.

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

Ответ 2

Насколько я знаю, close() - это правильный способ прервать заблокированный сокет. Прерывание и сохранение того, что, возможно, уже сделало частичное чтение или запись, делает вещи излишне сложными. Легче всего иметь дело с результатом "успеха" или "сдаться".

Ответ 3

DatagramSocket.receive блокирует, пока не получит датаграмму. Вероятно, вам нужно использовать setSoTimeout, чтобы сделать это таймаутом.