How to interrupt a blocking call to UDP socket'

2019-01-15 23:05发布

This question already has an answer here:

I have a UDP server listening packets from a client.

socket = new DatagramSocket(port);

while (isListen) {
    byte[] data = new byte[1024];
    DatagramPacket packet = new DatagramPacket(data, 0, data.length);
    socket.receive(packet);
}

The receive() method will wait forever before a packet received. Is it possible to stop waiting for receiving? I can set a boolean isListen to stop the loop. On the other hand, if the socket is waiting then it will wait forever if no packet send from the client.

2条回答
2楼-- · 2019-01-15 23:41

You can close the socket from another thread. The thread blocked in receive() will then throw an IOException.

while (isListen) {
    byte[] data = new byte[1024];
    DatagramPacket packet = new DatagramPacket(data, 0, data.length);
    try {
        socket.receive(packet);
    } catch(IOException e) {
        continue;
    }
}

void stopListening() { // Call me from some other thread
    isListen = false;
    socket.close();
}
查看更多
beautiful°
3楼-- · 2019-01-15 23:51

You need to set a socket timeout with the setSoTimeout() method and catch SocketTimeoutException thrown by the socket's receive() method when the timeout's been exceeded. After catching the exception you can keep using the socket for receiving packets. So utilizing the approach in a loop allows you to periodically (according to the timeout set) "interrupt" the receive() method call.

Note that timeout must be enabled prior to entering the blocking operation.

An example (w.r.t your code):

socket = new DatagramSocket(port);
socket.setSoTimeout(TIMEOUT_IN_MILLIS)

while (isListen) {
    byte[] data = new byte[1024];
    DatagramPacket packet = new DatagramPacket(data, 0, data.length);

    while (true) {
        try {
            socket.receive(packet);
            break;
        } catch (SocketTimeoutException e) {
            if (!isListen) {} // implement your business logic here
        }
    }
    // handle the packet received
}
查看更多
登录 后发表回答