Netty+;NioDatagram(UDP)和#x2B;ProtoBuf问题-丢弃的入站消息数据包

Netty+;NioDatagram(UDP)和#x2B;ProtoBuf问题-丢弃的入站消息数据包,udp,netty,protocol-buffers,Udp,Netty,Protocol Buffers,我正在尝试使用netty和NioDatagramChannel以及protoBuf作为消息构建一个UDP服务器。以下是服务器实现: EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioDatagramChannel.class) .option(ChannelOption.SO_BROADCAS

我正在尝试使用netty和NioDatagramChannel以及protoBuf作为消息构建一个UDP服务器。以下是服务器实现:

EventLoopGroup group = new NioEventLoopGroup();
try {
  Bootstrap b = new Bootstrap();
  b.group(group)
      .channel(NioDatagramChannel.class)
      .option(ChannelOption.SO_BROADCAST, true)
      .handler(new UdpProtoBufServerChannelInitializer());

  b.bind(port).sync().channel().closeFuture().await();
} finally {
  group.shutdownGracefully();
}
UdpProtoBufServerChannelInitializer:

public class UdpProtoBufServerChannelInitializer extends ChannelInitializer<NioDatagramChannel> {

    static final Logger logger = Logger.getLogger(UdpProtoBufServerChannelInitializer.class);
    @Override
      protected void initChannel(NioDatagramChannel ch) throws Exception {
        ChannelPipeline p = ch.pipeline();
        p.addFirst(new ProtobufVarint32FrameDecoder());
        p.addFirst(new ProtobufDecoder(Message.getDefaultInstance()));
        p.addFirst(new ProtobufVarint32LengthFieldPrepender());
        p.addFirst(new ProtobufEncoder());

        p.addFirst(new UdpProtoBufServerHandler());
    }
  }
公共类UdpProtoBufServerChannelInitializer扩展了ChannelInitializer{
静态最终记录器Logger=Logger.getLogger(UdpProtoBufServerChannelInitializer.class);
@凌驾
受保护的void initChannel(NioDatagramChannel ch)引发异常{
ChannelPipeline p=通道管道();
p、 addFirst(新的ProtobufVarint32FrameDecoder());
p、 addFirst(新的ProtobufDecoder(Message.getDefaultInstance());
p、 addFirst(新的Protobufvarint32长度字段Prepender());
p、 addFirst(新ProtobufEncoder());
p、 addFirst(新的UdpProtoBufServerHandler());
}
}
但是,在运行UdpProtoBufServerChannelInitializer之前从java客户端接收到消息后,我看到了以下错误

调试DefaultChannelPipeline:76-在管道尾部到达的丢弃入站消息DatagramPacket(/127.0.0.1:60556=>0.0.0.0/0.0.0:55559,PooledUnsafeHeapByteBuf(ridx:0,widx:34,cap:2048))。请检查您的管道配置

此外,不确定启动应用程序时的此异常是否相关:

    2017-05-22 14:31:09 DEBUG PlatformDependent0:91 - jdk.internal.misc.Unsafe.allocateUninitializedArray(int): unavailable
java.lang.ClassNotFoundException: jdk.internal.misc.Unsafe
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at io.netty.util.internal.PlatformDependent0$6.run(PlatformDependent0.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at io.netty.util.internal.PlatformDependent0.<clinit>(PlatformDependent0.java:288)
    at io.netty.util.internal.PlatformDependent.getSystemClassLoader(PlatformDependent.java:895)
    at io.netty.util.internal.PlatformDependent.isAndroid0(PlatformDependent.java:919)
    at io.netty.util.internal.PlatformDependent.<clinit>(PlatformDependent.java:70)
    at io.netty.util.ConstantPool.<init>(ConstantPool.java:32)
    at io.netty.util.Signal$1.<init>(Signal.java:27)
    at io.netty.util.Signal.<clinit>(Signal.java:27)
    at io.netty.util.concurrent.DefaultPromise.<clinit>(DefaultPromise.java:43)
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:36)
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:58)
    at io.netty.channel.MultithreadEventLoopGroup.<init>(MultithreadEventLoopGroup.java:52)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:87)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:82)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:63)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:51)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:43)
2017-05-22 14:31:09调试平台依赖0:91-jdk.internal.misc.Unsafe.allocateUninitializedArray(int):不可用
java.lang.ClassNotFoundException:jdk.internal.misc.Unsafe
位于java.net.URLClassLoader.findClass(URLClassLoader.java:381)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:424)
位于sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:357)
位于io.netty.util.internal.PlatformDependent0$6.run(PlatformDependent0.java:295)
位于java.security.AccessController.doPrivileged(本机方法)
位于io.netty.util.internal.PlatformDependent0。(PlatformDependent0.java:288)
位于io.netty.util.internal.PlatformDependent.getSystemClassLoader(PlatformDependent.java:895)
位于io.netty.util.internal.PlatformDependent.isAndroid0(PlatformDependent.java:919)
位于io.netty.util.internal.PlatformDependent.(PlatformDependent.java:70)
位于io.netty.util.ConstantPool(ConstantPool.java:32)
在io.netty.util.Signal$1。(Signal.java:27)
在io.netty.util.Signal.(Signal.java:27)
位于io.netty.util.concurrent.DefaultPromise。(DefaultPromise.java:43)
位于io.netty.util.concurrent.MultithreadEventExecutorGroup。(MultithreadEventExecutorGroup.java:36)
位于io.netty.util.concurrent.MultithreadEventExecutorGroup。(MultithreadEventExecutorGroup.java:58)
位于io.netty.channel.MultithreadEventLoopGroup。(MultithreadEventLoopGroup.java:52)
位于io.netty.channel.nio.NioEventLoopGroup。(NioEventLoopGroup.java:87)
位于io.netty.channel.nio.NioEventLoopGroup。(NioEventLoopGroup.java:82)
位于io.netty.channel.nio.NioEventLoopGroup。(NioEventLoopGroup.java:63)
位于io.netty.channel.nio.NioEventLoopGroup。(NioEventLoopGroup.java:51)
位于io.netty.channel.nio.NioEventLoopGroup。(NioEventLoopGroup.java:43)

嗯,看起来您的管道中没有消费者。您应该将自定义处理程序放在处理数据的位置。您可以在
p.addFirst(新的ProtobufVarint32FrameDecoder())之前执行此操作p.addFirst(新的MyHandler())进行编码>
或之后
p.addFirst(新的UdpProtoBufServerHandler())
p.addLast(新的MyHandler())


事实上,我可以假设您希望在代码中使用
addLast
而不是
addFirst
。如果使用
addLast
您将在管道
ProtobufVarint32FrameDecoder->ProtobufDecoder->…->UdpProtoBufServerHandler
。在您的情况下(使用
addFirst
),您将获得
UdpProtoBufServerHandler->ProtobufEncoder->…->Protobufvarint32帧解码器
看起来有点错误,因为您在第一个位置有一个处理程序,在最后有一个解码器。

谢谢大家。我终于想出了办法:

public class DatagramServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {

  @Override
  protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
      Message message = SocketProtos.Message.parseFrom(packet.content().nioBuffer());
      ctx.writeAndFlush(packet.retain());
  }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
      cause.printStackTrace();
      ctx.close();
   }
}
公共类DatagramServerHandler扩展了SimpleChannelInboundHandler{
@凌驾
受保护的无效channelRead0(ChannelHandlerContext ctx,DatagramPacket数据包)引发异常{
Message Message=SocketProtos.Message.parseFrom(packet.content().nioBuffer());
ctx.writeAndFlush(packet.retain());
}
@凌驾
公共无效例外情况(ChannelHandlerContext ctx,可丢弃原因){
cause.printStackTrace();
ctx.close();
}
}

只需使用NioDatagram UDP标准实现,然后将消息解析为字节[]到ProtoBuf消息。

感谢您的建议。更改为addLast后,我仍然看到相同的错误。这是我的实现:
ChannelPipeline p=ch.pipeline();p、 addLast(新的UdpProtoBufServerHandler());p、 addLast(新的ProtobufVarint32FrameDecoder());p、 addLast(新的ProtobufDecoder(Message.getDefaultInstance());p、 addLast(新的Protobufvarint32长字段Prepender());p、 addLast(新ProtobufEncoder());p、 addLast(新的UdpProtoBufServerHandler())