【问题标题】:Java InputStream read multi part messageJava InputStream 读取多部分消息
【发布时间】:2012-10-23 05:12:21
【问题描述】:

我有一个任务。从 InputStream 我应该收到多部分消息。前四个字节是消息长度,其他字节是消息体。同时可以接收多条消息。例如: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16

1,2,3,4 - length(in this case 4), 3,4,5,6 - body
7,8,9,10 - length (6), 11,12,13,14,15,16 - body

等等

我用这种方法计算的长度:

public static int byteArrayToInt(byte[] paRawBytes, int piOffset, boolean pbBigEndian) {

    int iRetVal = -1;

    if(paRawBytes.length < piOffset + 4)
        return iRetVal;

    int iLowest;
    int iLow;
    int iMid;
    int iHigh;

    if(pbBigEndian)
    {
        iLowest = paRawBytes[piOffset + 3];
        iLow    = paRawBytes[piOffset + 2];
        iMid    = paRawBytes[piOffset + 1];
        iHigh   = paRawBytes[piOffset];
    }
    else
    {
        iLowest = paRawBytes[piOffset];
        iLow    = paRawBytes[piOffset + 1];
        iMid    = paRawBytes[piOffset + 2];
        iHigh   = paRawBytes[piOffset + 3];
    }

    // Merge four bytes to form a 32-bit int value.
    iRetVal = (iHigh << 24) | (iMid << 16) | (iLow << 8) | (0xFF & iLowest);

    return iRetVal;
}

还有更多:

private static void getEventsList(byte[] bytesFromInputStream) {


    int start = 4;

    int end = getLength(bytesFromInputStream) + 4;

    byte[] tmp;

    tmp = Arrays.copyOfRange(bytesFromInputStream, start, end);


    eventsArrayList.add(tmp);

    if (bytesFromInputStream.length > end) {

        byte[] newArray = Arrays.copyOfRange(bytesFromInputStream, end, bytesFromInputStream.length);


        getEventsList(newArray);
    }


}

private static short getLength(byte[] bytes) {
    return ByteUtils.byteArrayToInt(Arrays.copyOfRange(bytes, 0, 4), 0, true);
}

但它不起作用,我没有更多的想法。请帮帮我

【问题讨论】:

  • 现在的输出是什么(这是错误的)?可能有助于调试...
  • 首先,您是否使用一些示例输入测试了您的byteArrayToInt 方法?对我来说,按位运算看起来不太正确。 this question 的回答中有一些示例实现
  • byteArrayToInt 工作正常,前两条消息读取良好,但其他消息长度不正确
  • 我需要递归函数。我永远不知道我及时收到了多少零件
  • 可以递归或迭代地执行此操作,但如果可能有大量消息,递归执行此操作是一个坏主意,因为您可能会导致堆栈溢出。

标签: java inputstream


【解决方案1】:

您最初提供的代码似乎无法编译(也许这是您遇到的问题,但您并没有真正指定)?

要修复它,我必须通过将byteArrayToInt 的结果转换为short 来让getLength() 返回short。或者您可以只返回一个int。我删除了对ByteUtils 的静态引用,因为我将所有方法都放在了一个类中。

我还在对byteArrayToInt 的调用中添加了0 的偏移量,以便方法签名匹配。

之后,您的代码似乎可以工作,至少在一些简单的情况下,例如:

byte[] message = new byte[]{0,0,0,1, 1, 0,0,0,2, 2,3};
getEventsList(message);

产生:

Got a message of length: 1
Content 1
Got a message of length: 2
Content 2
Content 3

(我也添加了一些println 语句)

您的byteArrayToInt 方法似乎不适用于较大的值(超过 16 位)。 this question 的答案中有一些示例实现(包括一些单行代码)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 2020-06-25
    • 2011-12-29
    • 2016-03-30
    • 2021-01-03
    • 2017-05-04
    相关资源
    最近更新 更多