Java 套接字超时不起作用

Java socket time out does not work

我有一个 class 负责监听另外两台具有完全相同 classes 的机器,因此它是一个由三台具有相同代码的计算机组成的网络。连接就在那里,我可以看到它们相互传递数据。一切正常。

当我取出其中一台机器并观察另外两台机器的行为时,事情变得棘手了。预计,当其中一台机器因某种原因停止工作时,其他两台应该继续工作。如果其中两个停止,其余的应该继续。

我尝试在下面实现这个机制。但是,当我取出其中一台机器时,程序一直在等待,所以它没有切换到 "two-way comparison mode"。

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

有什么想法吗?

好吧,我发现我弄错了。我需要更多端口(用于进出)。一旦我合并了这些端口,问题就没有再发生了。