SocketTimeoutException не выбрасывается

Следующий код должен генерировать исключение в зависимости от того, был ли достигнут тайм-аут:

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

Я пробовал во всех возможных сценариях, и я могу гарантировать, что пакет никогда даже не будет выброшен, поскольку он никогда не будет получен на другой стороне. Есть идеи, почему? Любая помощь приветствуется!


person mjr    schedule 18.04.2016    source источник


Ответы (2)


UDP — это протокол без установления соединения. Если вы отправляете пакет с использованием UDP, вы не будете знать, был получен пакет или нет. На принимающей стороне, если она пропустит пакет, она не узнает, что это произошло.

Единственный способ определить такие ситуации — создать протокол поверх UDP для обработки таких ситуаций, хотя, если вы не будете осторожны, вам лучше просто использовать TCP.

Примечание: setSoTimeout тайм-аут при блокировке чтения для TCP.

Включить/отключить SO_TIMEOUT с указанным временем ожидания в миллисекундах. Если для этой опции установлено ненулевое время ожидания, вызов read() для InputStream, связанного с этим сокетом, будет блокироваться только на это время. Если время ожидания истекает, возникает исключение java.net.SocketTimeoutException, хотя Socket все еще действителен. Опция должна быть включена до начала операции блокировки, чтобы она вступила в силу. Тайм-аут должен быть > 0. Нулевой тайм-аут интерпретируется как бесконечный тайм-аут.

это никогда не получено на другой стороне. Есть идеи, почему?

Если он не получен случайным образом, у вас есть проблема с сетью, из-за которой пакет отбрасывается. Вы можете сделать это реже, улучшив свою сеть, но это никогда не исчезнет.

Если он никогда не был получен, у вас проблема с конфигурацией. Либо трафик не направляется на этот хост (многие организации контролируют передачу UDP по своей сети), либо он блокируется брандмауэром, либо у вас неправильно настроены хост и порт. В отличие от TCP, вы не получите никакой информации о том, почему это происходит, в виде сообщения об ошибке, потому что отправителю ничего не возвращается.

person Peter Lawrey    schedule 18.04.2016
comment
Имеет смысл. Спасибо. - person mjr; 18.04.2016
comment
На самом деле, есть ли способ оторваться от socket.recieve(packet) в UDP через определенное время? - person mjr; 18.04.2016
comment
@mjr да, я думаю, это то, что вы ищете stackoverflow.com/questions/10055913/ - person Peter Lawrey; 18.04.2016

Следующий код должен генерировать исключение в зависимости от того, был ли достигнут тайм-аут:

Нет, не должно. DatagramSocket.setSoTimeout() устанавливает время ожидания чтения. На письмо это никак не влияет.

person user207421    schedule 18.04.2016