2016-11-03 2 views
0

동일한 클래스를 가진 두 대의 다른 머신을 청취하는 클래스가있어서 동일한 코드를 가진 세 대의 컴퓨터 네트워크입니다. 연결이 거기에 있고 나는 그들이 서로에게 데이터를 전달하는 것을 볼 수 있습니다. 될 때까지 모두 OK입니다.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

오케이 내가 착각 한 곳을 발견했습니다. 나는 더 많은 포트가 필요했다. 일단 내가이 항구들을 통합하면 문제는 다시는 발생하지 않았다.

관련 문제