java - 无法使用 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 中获取。
解决方案
您应该检查写入是否失败,如果是,原因:
...
ctx.writeAndFlush(new DatagramPacket(data, socketAdress)).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture f) {
if (!f.isSuccess()) {
f.cause().printStackTrace();
}
}
});
推荐阅读
- asp.net-mvc - 使用 MVC 单击 CheckBoxFor 时更改 DB 值
- batch-file - 运行批处理文件 - CPLEX Interactive Optimizer
- javascript - 如何在 TypeScript 中正确键入用作地图的 JavaScript 对象
- mongodb - 检查数组中是否存在字段
- c# - DelegatingHandler SendAsync 问题
- php - 全局临时表的 PHP Oracle 问题
- javascript - 糟糕的 ComponentDidMount 函数吞噬了我每天 95000 次调用 - ReactJS
- linux - 安装 docker 会导致主机上的 $hostname 解析为 docker 子网而不是 lan
- bash - bash 从期望脚本中获取退出状态
- authorization - XACML 3.0 和多种资源