代码之家  ›  专栏  ›  技术社区  ›  eric zhao

Netty服务器无法第二次接收客户端请求[已关闭]

  •  0
  • eric zhao  · 技术社区  · 9 年前

    我最近开始学习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 回复  |  直到 9 年前
        1
  •  1
  •   Ferrybig    9 年前

    你的问题是由以下事实造成的 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());
    }