无法在 netty 中连接 ssl

cannot connect with ssl in netty

我正在尝试通过 Netty 中的 SSL 示例和 EchoServer 示例,出于某种原因,当我在客户端添加我的 sslContext 时,我不断收到 an established connection was aborted by the software in your host machine

EchoServerBootstrap

public class EchoServerBootstrap {
    private final int port;

    public EchoServerBootstrap(int port) {
        this.port = port;
    }

    public static void main(String[] args) throws Exception {
        new EchoServerBootstrap(3000).start();
    }

    public void start() throws Exception {
        SelfSignedCertificate ssc = new SelfSignedCertificate();
        final SslContext sslContext = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();

        EventLoopGroup group = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group)
            .channel(NioServerSocketChannel.class)
            .localAddress(new InetSocketAddress(port))
            .handler(new LoggingHandler(LogLevel.INFO))
            .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(sslContext.newHandler(ch.alloc()));
                    ch.pipeline().addLast(new EchoServerHandler());
                }
            });
            ChannelFuture f = b.bind().sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }
}

EchoServerHandler

public class EchoServerHandler extends ChannelInboundHandlerAdapter {
        @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        System.out.println("Received: " + in.toString(CharsetUtil.UTF_8));
        ctx.write(in);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        System.out.println("channel read complete");
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }

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

EchoClientHandler

public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks", CharsetUtil.UTF_8));
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) {
        System.out.println("Client receive: " + in.toString(CharsetUtil.UTF_8));
    }

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

EchoClientBootstrap

public class EchoClientBootstrap {
    private final String host;
    private final int port;

    public EchoClientBootstrap(String host, int port) {
        this.port = port;
        this.host = host;
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();

        final SslContext sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();

        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
            .channel(NioSocketChannel.class)
            .remoteAddress(new InetSocketAddress(host, port))
            .handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(sslContext.newHandler(ch.alloc(), host, port)); // WHEN I ADD THIS LINE IT FAILS WITH I/O EXCEPTION 'an established connection was aborted...'
                    ch.pipeline().addLast(new EchoClientHandler());
                }
            });
            ChannelFuture f = b.connect(host, port).sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws Exception {

        new EchoClientBootstrap("localhost", 3000).start();
    }
}

我有什么明显的遗漏吗?我尝试按照此示例进行一些更改 (http://netty.io/4.1/xref/io/netty/example/securechat/package-summary.html),但是当我将 sslContext 添加到客户端通道时,我一直收到该异常。有什么想法吗?

我添加了一些日志记录来弄清楚发生了什么,在没有加密的情况下,EchoClient 发送 "Netty rocks" 消息,服务器读取消息并关闭通道。但是由于某种原因,如果启用了 SSL,则 EchoServerHandler 在 EchoClient 可以发送 "Netty rocks" 之前调用 channelReadComplete,这本质上就是这个方法

@Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        System.out.println("channel read complete");
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }

正在关闭我的频道。我不确定为什么在使用 SSL 时会出现这种差异。