2017-04-24 500 views
2

我正在使用基於幀的解碼器測試netty管道。如果我使用比最大幀小的緩衝區大小,它看起來像框架是不正確的。我正在測試包含兩條消息的文件。長度字段是第二件作品,包括整個消息的長度,包括長度字段和之前的作品。當緩衝區大小小於幀大小時,LengthFieldBasedFrameDecoder不能正確解析

new LengthFieldBasedFrameDecoder(65536, 4, 4, -8, 0) 

我正在讀取具有各種塊大小的文件。第一條消息的大小是348字節,第二條是456字節。如果使用512,346或更大的塊大小,則同時讀取兩個消息,並將其正確地組幀到下一個處理程序,該程序出於診斷目的將以十六進制字符串的形式輸出它接收到的緩衝區的內容。如果使用較小的塊大小,則會出現組幀錯誤。下面顯示了用於讀取和寫入文件的代碼。從與356個字節塊大小成功運行

public class NCCTBinAToCSV { 
    private static String inputFileName = "/tmp/combined.bin"; 
    private static final int BLOCKSIZE = 456; 
    public static void main(String[] args) throws Exception { 
     byte[] bytes = new byte[BLOCKSIZE]; 
     EmbeddedChannel channel = new EmbeddedChannel(
       new LengthFieldBasedFrameDecoder(65536, 4, 4, -8, 0), 
       new NCCTMessageDecoder(), 
       new StringOutputHandler()); 
     FileInputStream fis = new FileInputStream(new File(inputFileName)); 
     int bytesRead = 0; 
     while ((bytesRead = fis.read(bytes)) != -1) { 
      ByteBuf buf = Unpooled.wrappedBuffer(bytes, 0, bytesRead); 
      channel.writeInbound(buf); 
     } 
     channel.flush(); 
    } 
} 

輸出低於顯示(與消息體截斷爲簡潔

LOG:DEBUG 2017-04-24 04:19:24,675[main](netty.NCCTMessageDecoder) - com.ticomgeo.mtr.ncct.netty.NCCTMessageDecoder.decode(NCCTMessageDecoder.java:21) ]received 348 bytes 

Frame Start======================================== 

(byte) 0xbb, (byte) 0x55, (byte) 0x05, (byte) 0x16, 
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x5c, 
(byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x02, 
(byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
(byte) 0x50, (byte) 0x3a, (byte) 0xc9, (byte) 0x17, 

.... 
Frame End======================================== 

Frame Start======================================== 

(byte) 0xbb, (byte) 0x55, (byte) 0x05, (byte) 0x1c, 
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0xc8, 
(byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x02, 
(byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
(byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x01, 

如果我改變塊大小爲256,錯誤的字節似乎被解讀爲長度字段

Exception in thread "main" io.netty.handler.codec.TooLongFrameException: Adjusted frame length exceeds 65536: 4294967040 - discarded 
    at io.netty.handler.codec.LengthFieldBasedFrameDecoder.fail(LengthFieldBasedFrameDecoder.java:499) 
    at io.netty.handler.codec.LengthFieldBasedFrameDecoder.failIfNecessary(LengthFieldBasedFrameDecoder.java:477) 
    at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:403) 

回答

3

TL; DR;你的問題造成的,因爲網狀重用傳入bytebuf,然後要覆蓋內容

LengthFieldBasedFrameDecoder通過繼承來重新設計傳遞的ByteBuf,因爲通過垃圾回收使對象衰減是無用的,因爲它的引用計數是1,所以可以重用它。然而,問題來自於您正在改變在bytebuf中傳遞的內部信息,因此可以即時改變幀。使用傳入變量作爲存儲的wrappedBuffer(而不是製作wrappedBuffer)應該使用copiedBuffer,因爲該編譯器正確地創建了它的副本,因此LengthFieldBasedFrameDecoder的內部可以隨意使用它。

+0

奇妙地工作。感謝您的幫助。 –

+0

不要忘記接受解決問題的答案,這標誌着問題已解決,並允許其他在netty和java標記中處於活動狀態的用戶快速查看問題具有有效答案,您可以接受答案通過點擊複選標記 – Ferrybig