Netty 4二进制解码器问题

时间:2016-01-02 19:44:23

标签: java netty

我正试图从Mina转移到Netty 4并尝试实现101包含帧长度的标题组成的二进制帧解码器。作为Netty的完整新手,我在网上找到了一个例子并尝试执行它。我必须做一个新手错误,因为代码根据我的期望不起作用。这是代码:

public class NettyNioServer {

    public void server(int port) throws Exception {
       ServerBootstrap b = new ServerBootstrap();
        try {       
            b.group(new NioEventLoopGroup(), new NioEventLoopGroup())
            .channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_KEEPALIVE, true)
            .localAddress(new InetSocketAddress(port))
            .handler(new LoggingHandler(LogLevel.INFO))
            .childHandler(new ChannelInitializer<SocketChannel>() {

                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                   ChannelPipeline p = ch.pipeline();
                   p.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 2, 0, 2));
                   p.addLast("bytesDecoder", new ByteArrayDecoder());
                   p.addLast(new NioHandler());

                   }
        }); 
            ChannelFuture f = b.bind().sync();
            f.channel().closeFuture().sync();
        } finally {
            b.group()
             .shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws Exception {

        if (args.length != 1) {
            System.err.println(
                    "Usage: " + NettyNioServer.class.getSimpleName() +
                    " <port>");
            return;
        }
        int port = Integer.parseInt(args[0]);
        System.out.println("start on port: "+port);
        new NettyNioServer().server(port);
    }
}

处理程序代码如下:

public class NioHandler extends ChannelInboundHandlerAdapter {



@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
     byte[] bytes = (byte[]) msg;
     System.out.println(bytes.length+" bytes received");
}



@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
     ByteBuf buf1 =Unpooled.copiedBuffer("Well received bye! \r\n", Charset.forName("UTF-8"));
     ctx.writeAndFlush(buf1.duplicate()).addListener(ChannelFutureListener.CLOSE);
     System.out.println("Answer send");
}



@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    System.out.println("Exception caught: "+ cause.getMessage());

}



}

以下是我收到的内容:

start on port: 7777
janv. 02, 2016 8:15:47 PM io.netty.handler.logging.LoggingHandler channelRegistered
INFOS: [id: 0x01f2254e] REGISTERED
janv. 02, 2016 8:15:47 PM io.netty.handler.logging.LoggingHandler bind
INFOS: [id: 0x01f2254e] BIND(0.0.0.0/0.0.0.0:7777)
janv. 02, 2016 8:15:47 PM io.netty.handler.logging.LoggingHandler channelActive
INFOS: [id: 0x01f2254e, /0:0:0:0:0:0:0:0:7777] ACTIVE
janv. 02, 2016 8:17:14 PM io.netty.handler.logging.LoggingHandler logMessage
INFOS: [id: 0x01f2254e, /0:0:0:0:0:0:0:0:7777] RECEIVED: [id: 0x47c24c03, /127.0.0.1:50737 => /127.0.0.1:7777]
Answer send

为什么我的channelRead从未执行过?

1 个答案:

答案 0 :(得分:1)

您的处理程序实现似乎是正确的。

因此,此处理程序上没有读取任何数据。这是因为在管道之前的另一个处理程序捕获数据(可能是为了处理它)但它没有完成并且不会为管道上的其他处理程序推送数据。

确保根据LengthFieldBasedFrameDecoder规范在输入中正确写入数据:http://netty.io/4.0/api/io/netty/handler/codec/LengthFieldBasedFrameDecoder.html

如果你真的不需要,可以删除这个解码器。

您还可以添加管道的LoggingHandler顶部,以通过添加以下内容来查看收到的内容:

p.addFirst("logHandler", new LoggingHandler(LogLevel.INFO));

仅供参考,您的NioHandler还可以扩展SimpleChannelInboundHandler而不是更通用的ChannelInboundHandler