Need an interruptable way to listen for UDP packet

2019-03-06 12:11发布

问题:

I'm developing a Google Glass app which needs to listen for UDP packets in a worker thread (integrating with an existing system which sends UDP packets). I previously posted a question (see here) and received an answer which provided some guidance on how to do this. Using the approach in the other discussion I'll have a worker thread which is blocked on DatagramSocket.receive().

Further reading suggests to me that I'll need to be able to start/stop this on demand. So this brings me to the question I'm posting here. How can I do the above in such a way as to be able to interrupt (gracefully) the UDP listening? Is there some way I can "nicely" ask the socket to break out of the receive() call from another thread?

Or is there another way to listen for UDP packets in an interruptable fashion so I can start/stop the listener thread as needed in response to device events?

回答1:

My recommendation:

private DatagramSocket mSocket;

@Override
public void run() {
    Exception ex = null;
    try {
        // read while not interrupted
        while (!interrupted()) {
            ....
            mSocket.receive(...); // excepts when interrupted
        }
    } catch (Exception e) {
        if (interrupted())
            // the user did it
        else
            ex = e;
    } finally {
        // always release
        release();

        // rethrow the exception if we need to
        if (ex != null)
            throw ex;
    }
}

public void release() {
    // causes exception if in middle of rcv 
    if (mSocket != null) {
        mSocket.close();
        mSocket = null;
    }
}

@Override
public void interrupt() {
    super.interrupt();
    release();
}

clean cut, simple, always releases and interrupting stops you cleanly in 2 cases.