网络数据包和设置帧

时间:2017-11-19 21:06:43

标签: string authentication netty frame packet

目前我正在开发PacketSystem。通过这个,我创建了一个身份验证系统,并创建了一个从客户端发送到服务器的密钥,如下所示:

protected void channelRead0(ChannelHandlerContext ctx, Packet p) throws Exception {
    if(p instanceof PacketInServerAuthRequest) {
        System.out.println("Sending WrapperAuthKey. Waiting for answer...");
        send(new PacketOutServerAuthAnswer(NetworkUtils.readWrapperKey()));
    }
}

服务器以某种方式接收WrapperKey三次。最后两次没有数据包ID并导致这两个异常:

SEVERE: Nov 19, 2017 9:56:35 PM io.netty.channel.DefaultChannelPipeline onUnhandledInboundException
WARNUNG: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(8) + length(4) exceeds writerIndex(9): PooledUnsafeDirectByteBuf(ridx: 8, widx: 9, cap: 1024)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:442)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:624)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:559)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:476)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IndexOutOfBoundsException: readerIndex(8) + length(4) exceeds writerIndex(9): PooledUnsafeDirectByteBuf(ridx: 8, widx: 9, cap: 1024)
    at io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1396)
    at io.netty.buffer.AbstractByteBuf.readInt(AbstractByteBuf.java:766)
    at me.micha.flickcloud.netty.handler.PacketDecoder.decode(PacketDecoder.java:13)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
    ... 16 more

SEVERE: Nov 19, 2017 9:56:35 PM io.netty.channel.DefaultChannelPipeline onUnhandledInboundException
WARNUNG: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(16) + length(4) exceeds writerIndex(17): PooledUnsafeDirectByteBuf(ridx: 16, widx: 17, cap: 1024)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:442)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:624)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:559)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:476)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IndexOutOfBoundsException: readerIndex(16) + length(4) exceeds writerIndex(17): PooledUnsafeDirectByteBuf(ridx: 16, widx: 17, cap: 1024)
    at io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1396)
    at io.netty.buffer.AbstractByteBuf.readInt(AbstractByteBuf.java:766)
    at me.micha.flickcloud.netty.handler.PacketDecoder.decode(PacketDecoder.java:13)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
    ... 16 more

经过一些研究后我发现我可能必须使用LengthFieldPrepender和LengthFieldBasedFrameDecoder告诉服务器字符串何时结束,但我真的不知道使用它们。也许我在通过ByteBuf发送Strings时遇到了错误。

如果有人能解决我的问题,我将不胜感激。

编辑: 这就是我在双方(服务器和客户端)上启动频道的方式:

public static Channel initChannel(Channel channel) {
    channel.pipeline()
    .addLast(new PacketDecoder())
    .addLast(new PacketEncoder());

    return channel;
}

1 个答案:

答案 0 :(得分:0)

请记住,netty是一个异步/非阻塞框架,这意味着从Channel读取的数据可以被分段(就像TCP一般)。在ByteToMessageDecoder实施中尝试之前,您需要确保有足够的数据可供阅读。好像你试图读取一个Int并且没有剩下4个字节可供读取。

相关问题