gpt4 book ai didi

java - Netty 4.x中服务器没有实现客户端发送的消息

转载 作者:行者123 更新时间:2023-12-01 19:13:45 25 4
gpt4 key购买 nike

我尝试通过简单地实现以下示例来学习 Netty 4.x。我有一个服务器和一个客户端。在某个时间点,客户端想知道当前的日期时间,他会询问服务器“现在几点了?”。当服务器意识到问题时,他会回复当前的日期时间。

我的实现如下

TimeClientInboundHandler.java

public class TimeClientInboundHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf = (ByteBuf) msg;
try {
long currentTimeMillis = (byteBuf.readUnsignedInt() - 2208988800L) * 1000L;
System.out.println(new Date(currentTimeMillis));
ctx.close();
} finally {
byteBuf.release();
}
}

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.write("What time is it?");
ctx.flush();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}

TimeServerInboundHandler.java

public class TimeServerInboundHandler extends ChannelInboundHandlerAdapter {

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf = (ByteBuf) msg;
try {
byteBuf.readCharSequence(1024, StandardCharsets.UTF_8);
System.out.println(byteBuf.toString());
} finally {
((ByteBuf) msg).release();
}
}

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
final ByteBuf byteBuf = ctx.alloc().buffer(4);
byteBuf.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));

final ChannelFuture f = ctx.writeAndFlush(byteBuf);
f.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
assert f == future;
ctx.close();
}
});
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}

但是,我没有得到预期的结果。具体来说,在服务器端,问题是“现在几点了?”尚未在控制台上打印出来。

我实现了什么错误?

最佳答案

原因

造成这个问题的原因有两个。

服务器端无法实现客户端发送的消息,因为消息(从客户端)写入方式错误。而不是ctx.write("What time is it?"); ,我们应该执行如下ctx.write(Unpooled.coppiedBuffer("What time is it?", StandardCharsets.UTF_8);

此外,在TimeServerInboundHandler.java中,我们应该删除方法 channelActive() 。这是因为channelRead()永远不会被触发,但当然channelActive()当 channel 处于 Activity 状态时。

解决方案

TimeClientInboundHandler.java

public class TimeClientInboundHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf byteBuf = (ByteBuf) msg;
try {
System.out.println("Client received: " + byteBuf.toString(StandardCharsets.UTF_8));
ctx.close();
} finally {
byteBuf.release();
}
}

@Override
public void channelActive(ChannelHandlerContext ctx) {
ctx.writeAndFlush(Unpooled.copiedBuffer("What time is it?", StandardCharsets.UTF_8));
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

TimeServerInboundHandler.java

public class TimeServerInboundHandler extends ChannelInboundHandlerAdapter {

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf byteBuf = (ByteBuf) msg;
try {
System.out.println("Server received: " + byteBuf.toString(StandardCharsets.UTF_8));
String answer = Utils.getCurrentTime();
ctx.writeAndFlush(Unpooled.copiedBuffer(answer, StandardCharsets.UTF_8));
} finally {
((ByteBuf) msg).release();
}
}

@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

Utils.java

public class Utils {
public static String getCurrentTime() {
long currentTimeMillis = ((System.currentTimeMillis() / 1000L + 2208988800L) - 2208988800L) * 1000L;
return new Date(currentTimeMillis).toString();
}
}

关于java - Netty 4.x中服务器没有实现客户端发送的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59443210/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com