2016-11-03 88 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

好吧,我發現我錯了。我需要更多的端口(進出)。一旦我將這些端口合併,問題就不會再發生。