简体   繁体   English

处理在我的代码中引发EOFException的DataInputStream.readFully方法的最佳方法

[英]Best way to handle a DataInputStream.readFully method throwing an EOFException in my code

I am working with the DataInputStream.readFully method and trying to figure out the best way to handle the EOFException that is executed in this method. 我正在使用DataInputStream.readFully方法,并试图找出处理此方法中执行的EOFException的最佳方法。 I am getting this log entry and could use some help trying to find out what the problem is as this exception does not appear to be handled and my problem is stuck in a loop with this same error. 我正在获取此日志条目,并且可以使用一些帮助来尝试找出问题所在,因为似乎未处理此异常,并且我的问题陷入了具有相同错误的循环中。 Any help/direction would be appreciated. 任何帮助/方向将不胜感激。 Thank you. 谢谢。

    TRACE |     AccSysFNBBT-Socket-1-ReceiveQueuer-0 |                com.sharpbancsystems.ATM.channel.ActiveSocket |   528 |2013-11-22 11:10:02,311| - Received 2 bytes: 
S
  INFO |     AccSysFNBBT-Socket-1-ReceiveQueuer-0 |                com.sharpbancsystems.ATM.channel.ActiveSocket |   455 |2013-11-22 11:10:02,312| - Received message, length is 2643
  INFO |     AccSysFNBBT-Socket-1-ReceiveQueuer-1 |                com.sharpbancsystems.ATM.channel.ActiveSocket |   453 |2013-11-22 11:10:03,315| - Waiting for new message.
  WARN |     AccSysFNBBT-Socket-1-ReceiveQueuer-0 |                com.sharpbancsystems.ATM.channel.ActiveSocket |   483 |2013-11-22 11:10:03,315| - 
java.io.EOFException
    java.io.DataInputStream.readFully(Unknown Source)
    com.sharpbancsystems.ATM.channel.ActiveSocket.blockUntilGetMessageBytes(ActiveSocket.java:462)
    com.sharpbancsystems.ATM.channel.ActiveSocket.blockUntilReceiveMessage(ActiveSocket.java:266)
    com.sharpbancsystems.ATM.channel.ReceiveQueuer.run(ReceiveQueuer.java:113)
    java.lang.Thread.run(Unknown Source)

Here is my code where this is occurring: 这是发生这种情况的我的代码:

private byte[] blockUntilGetMessageBytes(final Request request, final ProcessingTimer timer) throws ChannelException {

    byte[] data = null;
    int len;        
    try {
        // have to synchronize on the dataInputStream because the class was designed to have more than one ReceiveQueuer using this method
        synchronized (dataInputStream) {
            LOGGER.info("Waiting for new message.");
            len = blockUntilGetMessageLength();
            LOGGER.info("Received message, length is " + len);

            if (!owningChannel.shouldTerminate) {
                if (len > 0 && len <= 15000) {
                    request.setTimeStampDataFieldAsTimestamp(RequestConstants.SaveDataField.FromStartReceiveTMS);
                    timer.start();
                    data = new byte[len];
                    dataInputStream.readFully(data, 0, len);

                    LOGGER.trace("Full message: " + new String(data));
                    request.setTimeStampDataFieldAsTimestamp(RequestConstants.SaveDataField.FromFinishReceiveTMS);
                    timer.finish();
                    request.setNanosecondDataField(RequestConstants.SaveDataField.FromReceiveNS, timer.nanos());
                    if (channelStats != null) {
                        channelStats.addBytesReceived(data.length + 2); // include the 2 bytes for the length indicator
                        channelStats.increaseReceivedMsgs();
                    }
                } else if (len == 0) {
                    // Should probably log it, but continue
                    LOGGER.info("Empty message received.");
                    throw new ChannelException(getBankID(), "Empty message received");
                } else {
                    throw new ISOException("Invalid receive length: " + len + ".");
                }
            }
        }
        return data;
    } catch (final Exception ex) {
        LOGGER.warn(FormatData.fullStackTrace(ex));
        throw new ChannelException(getChannelID().getNumericId(), this.getClass().getSimpleName().concat(".getMessageBytes()"), ex);
    }
}

protected int blockUntilGetMessageLength() {
    final byte[] b = new byte[2];
    try {
        dataInputStream.readFully(b, 0, 2);
    } catch (final EOFException ex){
        // ***** 20131022 MS - Per Shannon add getNeedReconnect() here. *****
        getNeedReconnect().set(true);
        socket.isConnected();
        // ***** 20131022 MS - Per Shannon this means there was a premature EOF. *****
        if (this.shouldTerminate) {
            return 0;
        } else {
            synchronized (socket) {
                socket.notify();
            }
            LOGGER.warn(FormatData.formatStack(ex));
        }
    } catch (final IOException ex) {
        // ***** 20131022 MS - Per Shannon add getNeedReconnect() here. *****
        getNeedReconnect().set(true);
        socket.isConnected();
        if (this.shouldTerminate) {
            return 0;
        } else {
            synchronized (socket) {
                socket.notify();
            }
            LOGGER.warn(FormatData.formatStack(ex));
            return 0;
        }
    }
    LOGGER.trace("Received 2 bytes: " + new String(b));
    return ((((b[0]) & BYTEMASK) << BYTESHIFT) | ((b[1]) & BYTEMASK));
}

You get the exception, because len is greater than the number of bytes you can read from the stream. 您会得到一个例外,因为len大于您可以从流中读取的字节数。 So apparently blockUntilGetMessageLength(); 因此显然blockUntilGetMessageLength(); returns a bad value. 返回错误的值。

Without knowing how you compute len , it's not possible to tell you how to really fix this. 在不知道如何计算len ,不可能告诉您如何真正解决此问题。 But in any case, you could simply do something like this: 但是无论如何,您都可以执行以下操作:

public final int readFully(InputStream in, byte b[], int off, int len) throws IOException {
    if (len < 0)
        throw new IndexOutOfBoundsException();
    int n = 0;
    while (n < len) {
        int count = in.read(b, off + n, len - n);
        if (count < 0)
            break;
        n += count;
    }
    return n;
}

The method would return the number of bytes really read. 该方法将返回实际读取的字节数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM