2016-11-03 2 views
0

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

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

Я попытался реализовать этот механизм ниже. Однако, когда я вынимаю одну из машин, программа продолжает ждать, поэтому она не переключается на «режим двустороннего сравнения».

public void listen() { 
    try { 
    logger.info("Creating listener sockets"); 

    while (isRunning) { 
     final byte[] buf = new byte[bufferSize]; 

     final DatagramPacket packetOne = new DatagramPacket(buf, buf.length); 
     final DatagramPacket packetTwo = new DatagramPacket(buf, buf.length); 
     MediatorMessageMsg mediatorMessageOne = null; 
     MediatorMessageMsg mediatorMessageTwo = null; 

     try { 
      socketReceiverOne.receive(packetOne); 
      ByteArrayInputStream firstInput = new ByteArrayInputStream(buf); 
      mediatorMessageOne = MediatorMessageMsg.parseDelimitedFrom(firstInput); 

      socketReceiverTwo.receive(packetTwo); 
      ByteArrayInputStream secondInput = new ByteArrayInputStream(buf); 
      mediatorMessageTwo = MediatorMessageMsg.parseDelimitedFrom(secondInput); 

      logger.trace("Received packets"); 
     } catch (final SocketTimeoutException e) { 
      logger.trace(e.getMessage()); 
      continue; 
     } catch (final SocketException e) { 
      logger.warn(e); 
      logger.warn("Ignore the error and go on."); 
      continue; 
     } catch (final IOException e) { 
      logger.error("Incoming communication stopped!"); 
      logger.error(e); 
      stop(); 
     } 

     // if two mediators sent the data, it's OK 
     if (packetOne.getLength() > 0 && packetTwo.getLength() > 0) { 
      handlePackets(mediatorMessageOne, mediatorMessageTwo); 
      logger.info("Number of active mediators: 2. Comparison style: 1v1v1"); 
     } 
     // if only one sent the data, compare it with our own 
     else if (packetOne.getLength() > 0 || packetTwo.getLength() > 0) { 
      // whicehever sent the data, compare its data with our own 
      logger.info("Number of active mediators: 1. Comparison style: 1v1"); 
      if (packetOne.getLength() > 0) { 
       handlePackets(mediatorMessageOne); 
      } else { 
       handlePackets(mediatorMessageTwo); 
      } 

     } 
     // if no data is sent, then pass our own directly 
     else { 
      logger.info("Number of active mediators: 0. Comparison style: No Comparison"); 
      // our datamodel to retrieve data on our own 
      DataModel modelOwn = DataModel.getInstance(); 
      MediatorMessageMsg newMessage = MediatorMessageMsg.newBuilder().setHeading(modelOwn.getHeading()).setSpeed(modelOwn.getSpeed()).setSender(getId()).build(); 
      // publish(topicName, newMessage); 
     } 

     Thread.sleep(1); 
    } 

    socketReceiverOne.close(); 
    socketReceiverTwo.close(); 
    logger.info("stopped"); 

} catch (final IllegalArgumentException e) { 
    logger.error("Illegal argument received: " + e); 
} catch (final Exception e) { 
    logger.error("Unexpected error occured: " + e); 
} finally { 
    if (socketReceiverOne instanceof DatagramSocket && socketReceiverTwo instanceof DatagramSocket) { 
     if (!socketReceiverOne.isClosed() || !socketReceiverTwo.isClosed()) { 
      socketReceiverOne.close(); 
      socketReceiverTwo.close(); 
     } 
    } 
} 

} 

Чтобы сэкономить ваше время, позвольте мне поделиться своим мнением по этому вопросу. Я подозреваю, что проблема будет в этой части:

  socketReceiverOne.receive(packetOne); 
      ByteArrayInputStream firstInput = new ByteArrayInputStream(buf); 
      mediatorMessageOne = MediatorMessageMsg.parseDelimitedFrom(firstInput); 

      socketReceiverTwo.receive(packetTwo); 
      ByteArrayInputStream secondInput = new ByteArrayInputStream(buf); 
      mediatorMessageTwo = MediatorMessageMsg.parseDelimitedFrom(secondInput); 

Мне кажется, что программа ожидает пакет и когда он не может получить его, он продолжает ждать. Хотя у меня есть исключение из условия исключения, я не могу это сделать.

private int socketTimeout = 1000 * 2;// 2sec 
socketReceiverOne.setSoTimeout(socketTimeout); 
socketReceiverTwo.setSoTimeout(socketTimeout); 

Любые мысли?

+0

Возможно, вы должны использовать отдельные блоки 'try' для каждого приема. Если первый не удался, второй пропущен. –

ответ

0

Хорошо, я нашел, где я ошибся. Мне нужно больше портов (для входа и выхода). Как только я включил эти порты, проблема не повторилась.

Смежные вопросы