如何中断阻塞调用UDP socket的receive()[重复]

问题描述 投票:-1回答:2

这个问题在这里已有答案:

我有一个UDP服务器监听来自客户端的数据包。

socket = new DatagramSocket(port);

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

receive()方法将在收到数据包之前永远等待。是否有可能停止等待接收?我可以设置一个boolean isListen来阻止循环。另一方面,如果套接字正在等待,那么如果没有从客户端发送数据包,它将永远等待。

java sockets network-programming udp
2个回答
0
投票

您可以从另一个线程关闭套接字。然后在receive()中阻塞的线程将抛出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();
}

0
投票

您需要使用setSoTimeout()方法设置套接字超时,并在超过超时时捕获SocketTimeoutExceptionsocket方法抛出的receive()。捕获异常后,您可以继续使用套接字接收数据包。因此,在循环中使用该方法允许您定期(根据超时设置)“中断”receive()方法调用。

请注意,必须在进入阻止操作之前启用超时。

一个例子(w.r.t你的代码):

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
}
© www.soinside.com 2019 - 2024. All rights reserved.