2012-10-22 92 views
1

我有一個任務。從InputStream我應該收到多部分消息。前四個字節是消息長度,其他字節是消息正文。同時可以收到很多消息。例如: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16Java InputStream讀取多部分消息

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

但它不工作,我沒有更多的想法。請幫助我

+0

什麼是現在輸出(這是錯誤的)?可能有助於調試... – justderb

+0

首先,您是否使用一些示例輸入測試了您的'byteArrayToInt'方法?按位操作對我來說看起來不太合適。在[這個問題]的答案中有一些示例實現(http://stackoverflow.com/questions/7619058/convert-a-byte-array-to-integer-in-java-and-vise-versa) – DNA

+0

byteArrayToInt工作正常,前兩條消息讀取良好,但其他長度不正確 – NikedLab

回答

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的答案中有一些示例實現(包括一些單行)。