未抛出 SocketTimeoutException

SocketTimeoutException not being thrown

以下代码应根据是否达到超时抛出异常:

public boolean isAlive(int workerNum) throws Exception
{
    System.out.println("Checking worker #" + workerNum + " from " + 
        getWorkerAddress(workerNum)
        + " at port " + getWorkerPort(workerNum));

    DatagramPacket packet = new DatagramPacket("__ping__".getBytes(), "__ping__".length(), 
                getWorkerAddress(workerNum), getWorkerPort(workerNum));
    socket.setSoTimeout(10000);
    try {
        System.out.println("Checking worker #" + workerNum);
        socket.send(packet);
    } catch (SocketTimeoutException  e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

我已经尝试了所有可能的情况,我可以保证数据包永远不会被丢弃,因为它从未在另一端收到。知道为什么吗?非常感谢任何帮助!

UDP 是一种无连接协议。如果您使用 UDP 发送数据包,您将不知道数据包是否已收到。在接收方,如果它错过了一个数据包,它不会知道发生了什么。

确定这些情况的唯一方法是在 UDP 之上构建一个协议来处理这些情况,但如果您不小心,使用 TCP 会更好。

注意:setSoTimeout 是 TCP 阻塞读取超时。

Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.

it is never recieved on the other side. Any idea why?

如果不是随机收到,则说明您遇到了网络问题,即数据包被丢弃。您可以通过改善网络来减少这种情况的发生,但它永远不会消失。

如果从未收到,则说明您有配置问题。要么流量没有路由到该主机(许多组织控制 UDP 在其网络中的传递方式),要么被防火墙阻止,或者您的主机和端口配置不正确。与 TCP 不同,您不会通过错误消息获得任何关于为什么会发生这种情况的信息,因为没有任何信息返回给发件人。

The following code should throw an exception based on whether a timeout was reached:

不应该。 DatagramSocket.setSoTimeout() 设置 read 超时。对写入没有影响。