我最近开始学习Netty,但今天我遇到了问题。 这是我的服务器代码
public class NettyServer2 {
public static void main(String[] args) {
System.out.println("Server start");
new NettyServer2().start();
}
public void start() {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
ChannelInitializer<SocketChannel> channelInit = new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new SeverHandler());
}
};
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(channelInit)
.option(ChannelOption.SO_BACKLOG, 1024).childOption(ChannelOption.SO_KEEPALIVE, true);
try {
ChannelFuture f = b.bind(8000).sync();
System.out.println("server started on port:8000");
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
bossGroup.shutdownGracefully().sync();
workerGroup.shutdownGracefully().sync();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
类SeverHandler扩展了SimpleChannelInboundHandler {
@Override
protected void messageReceived(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
System.out.println("server recevie:" + in.toString(CharsetUtil.UTF_8));
ctx.writeAndFlush(in);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
Channel ch = ctx.channel();
if (ch.isActive()) {
ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
}
}
并且有我的客户代码
public class NettyClient2 {
private final String host;
private final int port;
public NettyClient2(String host, int port) {
this.host = host;
this.port = port;
}
public void start() throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
ChannelInitializer<SocketChannel> channel = new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
channel.pipeline().addFirst(new ClientHandler());
}
};
b.group(group).channel(NioSocketChannel.class).remoteAddress(new InetSocketAddress(host, port))
.handler(new ClientHandler());
try {
ChannelFuture f = b.connect().sync();
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
group.shutdownGracefully().sync();
}
}
public static void main(String[] args) throws InterruptedException {
new NettyClient2("127.0.0.1", 8000).start();
}
}
类ClientHandler扩展了SimpleChannelInboundHandler {
private BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("已经与Server建立连接...");
System.out.println("\n请输入要发送的信息:");
String in = sin.readLine();
ctx.writeAndFlush(Unpooled.copiedBuffer(in,CharsetUtil.UTF_8));
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
System.out.println("client recevie:" + in.toString(CharsetUtil.UTF_8));
System.out.println("已经与Server建立连接...");
System.out.println("\n请输入要发送的信息:");
String read = sin.readLine();
ctx.writeAndFlush(Unpooled.copiedBuffer(read,CharsetUtil.UTF_8));
}
}
当客户端启动时,我在客户端控制台上输入,服务器将收到请求,但是当我第二次请求服务器无法收到请求时,我收到错误。 enter image description here
答案 0 :(得分:1)
您的问题是由SimpleChannelInboundHandler
自动为您释放缓冲区引起的。
要解决此问题,您应该在发送时在缓冲区上调用retain()
。
@Override
protected void messageReceived(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
System.out.println("server recevie:" + in.toString(CharsetUtil.UTF_8));
ctx.writeAndFlush(in.retain());
}