1

構築中のアプリケーション用にフレーム デコーダを実装しました。これまでのところ、コードを実行すると、パケットは適切にデコードされ、受信されたパケットが正しいことがわかります。ただし、例外が発生します。

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 Arsene * */

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

誰かが私のコードの何が間違っているのか教えて、その例外を解決するのを手伝ってもらえますか?

4

1 に答える 1

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;
    }   
}
于 2013-03-12T14:55:12.823 に答える