首页 > 解决方案 > 无法使用 Netty UDP 和 SimpleChannelInboundHandler 在指定地址发送消息

问题描述

我有 Netty 服务器,它监听一些端口并发送对传入消息的响应。服务器实现:

@Override
public void run() {
    final NioEventLoopGroup group = new NioEventLoopGroup();
    try {
        log.info("Started listening logs ...");
        final Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group).channel(NioDatagramChannel.class)
                .option(ChannelOption.SO_BROADCAST, true)
                .handler(new ChannelInitializer<NioDatagramChannel>() {
                    @Override
                    public void initChannel(final NioDatagramChannel nioDatagramChannel) {
                        ChannelPipeline channelPipeline = nioDatagramChannel.pipeline();
                        channelPipeline.addLast(encryptedPacketHandlerChain);
                    }
                });

        // Bind and start to accept incoming connections.
        InetAddress address = InetAddress.getByName("localhost");

        bootstrap.bind(address, LOG_PORT).sync().channel().closeFuture().await();
    } catch (Exception e) {
        log.error("Unexpected error happened", e);
    } finally {
        System.out.print("Stop server");
    }
}

EncryptedPacketHandlerChain 实现:

@Override
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket datagramPacket) {
    final String hostAddress = datagramPacket.sender().getAddress().getHostAddress();
    final ByteBuf byteBuffer = datagramPacket.content();
    final int receivedPacketLength = byteBuffer.readableBytes();
    final byte[] receivedPacket = new byte[receivedPacketLength];
    byteBuffer.readBytes(receivedPacket);

    EncryptedPacket encryptedPacket = EncryptedPacket.fromBytes(receivedPacket);

    byte[] response = EncryptedPacket.toBytes(handle(encryptedPacket, hostAddress));

    System.out.println("Response\n" + Arrays.toString(response));

    ByteBuf data = ctx.alloc().buffer(response.length);
    data.writeBytes(response);

    InetSocketAddress socketAddress = datagramPacket.sender();
    ctx.write(new DatagramPacket(data, socketAddress));
    ctx.flush();
    
    System.out.println("Send to " + socketAddress);
    }

这是我在官方 netty文档中阅读的非常简单的实现。但是当我在 127.0.0.2 主机地址上从本地发件人发送请求后,我没有得到 Netty 服务器的响应。当我使用 java.net DatagramSocket 发送响应时,一切正常,但我需要从同一个套接字(即 Netty)响应发件人地址和端口。我的代码有什么问题?

UPD:我需要从 netty 在指定地址和指定端口上发送响应,我可以从收入 datagramPacket 中获取。

标签: javaudpnetty

解决方案


您应该检查写入是否失败,如果是,原因:

...
ctx.writeAndFlush(new DatagramPacket(data, socketAdress)).addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture f) {
        if (!f.isSuccess()) {
            f.cause().printStackTrace();
        }
    }  
 });

推荐阅读