Netty服务器第二次无法接收客户端请求

时间:2016-03-25 03:25:22

标签: netty

我最近开始学习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

1 个答案:

答案 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());
}