不抛出SocketTimeoutException

时间:2016-04-18 06:41:46

标签: java sockets udp socket-timeout-exception

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

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;
}

我已经尝试过各种可能的情况,我可以保证数据包永远不会被抛出,因为它从未被收到过。知道为什么吗?非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

  

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

不,不应该。 DatagramSocket.setSoTimeout()设置读取超时。它对写作没有影响。

答案 1 :(得分:1)

UDP是一种无连接协议。如果使用UDP发送数据包,则无法确定是否已收到数据包。在接收方,如果它错过了一个数据包,它将不知道发生了这种情况。

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

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

  

使用指定的超时启用/禁用SO_TIMEOUT,以毫秒为单位。如果将此选项设置为非零超时,则与此Socket关联的InputStream上的read()调用将仅阻止这段时间。如果超时到期,则引发java.net.SocketTimeoutException,尽管Socket仍然有效。必须在进入阻止操作之前启用该选项才能生效。超时必须> 0.超时为零被解释为无限超时。

     

它永远不会在另一边收到。知道为什么吗?

如果没有随机收到,则会出现丢弃数据包的网络问题。你可以通过改善你的网络来减少这种情况,但它永远不会消失。

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