2013-03-12 37 views
1

我已經爲我正在構建的應用程序實現了一個幀解碼器。到目前爲止,當我運行代碼時,數據包被很好地解碼,我可以看到接收到的數據包並且是正確的。但是我得到一個異常:Netty Framedecoder錯誤

decode() method must read at least one byte if it returned a frame (caused by: class com.smsgh.unitysmpp.Plugins.Smp.SmpPduFrameDecoder) 
    at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:434) 
    at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:303) 
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) 
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) 
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:84) 
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:471) 
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:332) 
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 

這是我寫的代碼: /** * @author溫格 * */

public class SmpPduFrameDecoder extends FrameDecoder { 

    private static Logger logger = LoggerFactory.getLogger(SmpPduFrameDecoder.class); 


    @Override 
    protected Object decode(ChannelHandlerContext ctx, Channel channel, 
      ChannelBuffer buffer) throws Exception { 

     ChannelBuffer leFrame = null; 
     // Check the Endianness of the packet sent 
     if(buffer.order() == ByteOrder.BIG_ENDIAN){ 
      if(buffer.hasArray()){ 
       leFrame = ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, buffer.array(), buffer.arrayOffset(), buffer.capacity()); 
      } 
      else{ 
       leFrame = ChannelBuffers.wrappedBuffer(buffer.toByteBuffer().order(ByteOrder.LITTLE_ENDIAN)); 
      } 
     } 

     // Read the byte length 
     // wait until the length prefix is available 
     if (leFrame.readableBytes() < 4) { 
      logger.debug("Unable to Read the Length"); 
      return null; 
     } 

     // parse the frame length (first 4 bytes) 
     int frameLength = leFrame.getInt(leFrame.readerIndex()); 
     logger.info("Packet Received Length " + frameLength); 

     // wait until the whole data is available 
     if (leFrame.readableBytes() < frameLength) { 
      logger.debug("Unable to read the full PDU received"); 
      return null; 
     } 

     leFrame.skipBytes(4); 

     int readerIndex = leFrame.readerIndex(); 
     ChannelBuffer frame = leFrame.readBytes(frameLength);  
     leFrame.readerIndex(readerIndex+frameLength); 

     byte[] byteArray = frame.array(); 
     StringBuilder sb = new StringBuilder(); 
     for(byte b : byteArray){ 
      sb.append(HexUtil.toHexString(b)); 
     } 
     logger.info("Decode Frame Received without the length " +sb.toString());   
     logger.debug("Full PDU has been read"); 
     return frame; 
    } 
} 

誰能告訴我什麼是錯eith我的代碼並幫助我解決這個異常?

回答

1

我已經解決了這個問題。代替將緩衝區複製到新緩衝區中,我只需使用swapInt來獲得實際的幀長度,如下所示:

public class SmpPduFrameDecoder extends FrameDecoder { 

    private static Logger logger = LoggerFactory.getLogger(SmpPduFrameDecoder.class); 


    @Override 
    protected Object decode(ChannelHandlerContext ctx, Channel channel, 
      ChannelBuffer buffer) throws Exception { 

     // Read the byte length 
     // wait until the length prefix is available 
     if (buffer.readableBytes() < 4) { 
      logger.debug("Unable to Read the Length"); 
      return null; 
     } 

     // parse the frame length (first 4 bytes) 
     //int frameLength = leFrame.getInt(leFrame.readerIndex()); 
     int frameLength = ChannelBuffers.swapInt(buffer.getInt(buffer.readerIndex())); 
     logger.info("Packet Received Length " + frameLength); 

     // wait until the whole data is available 
     if (buffer.readableBytes() < frameLength) { 
      logger.debug("Unable to read the full PDU received"); 
      return null; 
     } 

     buffer.skipBytes(4); 
     ChannelBuffer frame = buffer.readBytes(frameLength); 
     buffer.readerIndex(frameLength + 4); 

     byte[] byteArray = frame.array(); 
     StringBuilder sb = new StringBuilder(); 
     for(byte b : byteArray){ 
      sb.append(HexUtil.toHexString(b)); 
     } 
     logger.info("Decode Frame Received without the length " +sb.toString());   
     logger.debug("Full PDU has been read"); 
     return frame; 
    } 
} 
相關問題