Interrupt a thread in DatagramSocket.receive
Asked Answered
E

3

24

I'm building an application that listens on both TCP and UDP, and I've run into some trouble with my shutdown mechanism. When I call Thread.interrupt() on each of the listening threads, the TCP thread is interrupted from listening, whereas the UDP listener isn't. To be specific, the TCP thread uses ServerSocket.accept(), which simply returns (without actually connecting). Whereas the UDP thread uses DatagramSocket.receive(), and doesn't exit that method.

Is this an issue in my JRE, my OS, or should I just switch to (Datagram)Socket.close()?

UPDATE: I've found an analysis of the problem. It confirms that the behavior is not consistent.

Elviaelvie answered 12/1, 2011 at 15:39 Comment(3)
Just to help anyone else dealing with the same issue: My ServerSocket.accept() wasn't returning without connecting. It was returning because my browser (FF4b10) requests the favicon 3 times. One of the requests was tripping the Thread.interrupted() check.I'll be switching over to using close().Elviaelvie
link is dead, could you update with a new one?Devland
Wayback machine doesn't have that specific article, and I don't remember the exact title. The gist is that you'd expect the behavior of ServerSocket to match DatagramSocket more or less, but they handle interruptions/socket closure differently.Elviaelvie
F
35

A common idiom for interrupting network IO is to close the channel. 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();
   }
}
Froebel answered 12/1, 2011 at 16:17 Comment(1)
Couldn't have worded it better myself. Thanks!Elviaelvie
H
3

As far as I know, close() is the proper way to interrupt a blocked socket. 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.

Hacksaw answered 12/1, 2011 at 16:25 Comment(0)
R
0

DatagramSocket.receive blocks until it receives a datagram. Probably what you need to do is use setSoTimeout to make it timeout.

Radiolarian answered 12/1, 2011 at 15:49 Comment(2)
Timeout is not an acceptable solution in this case. Also, DatagramSocket.receive() should be interrupted, which is why this is weird.Elviaelvie
@SEK: no it shouldn't. There is nothing in the Javadoc that says so. If you want interruptible behaviour you need to use DatagramChannel, which implements InterruptibleChannel.Bine

© 2022 - 2024 — McMap. All rights reserved.