使用DelimiterBasedFrameDecoder和解码时,netty客户端无法从服务器接收响应

时间:2017-08-30 05:43:29

标签: netty

客户端:

public class Client {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup workgroup = new NioEventLoopGroup();
        final Bootstrap b = new Bootstrap();
        b.group(workgroup)
                .channel(NioSocketChannel.class) 
                .handler(new ChannelInitializer<SocketChannel>() {
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
                        socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,buf));
                        socketChannel.pipeline().addLast(new StringDecoder());
                        socketChannel.pipeline().addLast(new ClientHandler());
                    }
                });

        ChannelFuture cf = b.connect("127.0.0.1",8765); 

//        cf.channel().writeAndFlush(Unpooled.copiedBuffer("aa$_".getBytes()));
//        cf.channel().writeAndFlush(Unpooled.copiedBuffer("bbbb$_".getBytes()));

        cf.channel().closeFuture().sync();
        workgroup.shutdownGracefully();
    }

}

ClientHandler的:

public class ClientHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("Start");
        ctx.writeAndFlush(Unpooled.copiedBuffer("aa$_".getBytes()));
        ctx.writeAndFlush(Unpooled.copiedBuffer("bbbb$_".getBytes()));
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            String response = (String)msg;
            System.out.println("Server feedback: "+ response);
        }finally {
            ReferenceCountUtil.release(msg);
        }
    }

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

服务器:

public class Server {
    public static void main(String[] args) throws InterruptedException {

        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        final ServerBootstrap  b = new ServerBootstrap();

        b.group(bossGroup,workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
                        socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,buf));
                        socketChannel.pipeline().addLast(new StringDecoder());
                        socketChannel.pipeline().addLast(new ServerHandler());
                    }
                });

        ChannelFuture future = b.bind(8765).sync();

        future.channel().closeFuture().sync();

        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();

    }
}

Serverhandler:

public class ServerHandler extends ChannelInboundHandlerAdapter{
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        String str = (String)msg;
        System.out.println("Client: "+str);
//        String response = "Server";
//        response = response+"$_";
        ctx.writeAndFlush(Unpooled.copiedBuffer("Server!!!!$_".getBytes()));
    }

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

如果我直接通过客户端发送消息,请使用cf.channel(),如下所示:

cf.channel().writeAndFlush(Unpooled.copiedBuffer("aa$_".getBytes()));
cf.channel().writeAndFlush(Unpooled.copiedBuffer("bbbb$_".getBytes()));

客户端和服务器都不接收数据。

但是如果我在客户端注释掉decode和DelimiterBasedFrameDecoder的代码(clientHandler需要使用Bytebuf),客户端和服务器都可以接收消息,尽管服务器收到的消息已经解压缩(只有客户端有问题) )

Server feedback: Server!!!!$_Server!!!!$_

如果我通过channelActive在clientHandler中发送消息:

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    System.out.println("Start");
    ctx.writeAndFlush(Unpooled.copiedBuffer("aa$_".getBytes()));
    ctx.writeAndFlush(Unpooled.copiedBuffer("bbbb$_".getBytes()));
}

它工作正常。

Server feedback: Server!!!!
Server feedback: Server!!!!

在clientHandler中使用cf.channel()ctx发送邮件有什么区别?

Netty 4.1.15

0 个答案:

没有答案