我有一个netty客户端,等待不间断地让服务器发送一些东西 . 这似乎在版本3.7中工作正常 . 我试图将它迁移到4.0但我不断得到例外:

javax.net.ssl.SSLException: handshake timed out
    nioEventLoopGroup-2-1, called closeOutbound()
    nioEventLoopGroup-2-1, closeOutboundInternal()
    nioEventLoopGroup-2-1, SEND TLSv1 ALERT:  warning, description = close_notify
    nioEventLoopGroup-2-1, WRITE: TLSv1 Alert, length = 2
    nioEventLoopGroup-2-1, called closeInbound()
    nioEventLoopGroup-2-1, fatal error: 80: Inbound closed before receiving peer's close_notify: possible truncation attack?
    javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
    nioEventLoopGroup-2-1, SEND TLSv1 ALERT:  fatal, description = internal_error
    nioEventLoopGroup-2-1, Exception sending alert: java.io.IOException: writer side was already closed.

我在3.7 netty版本中有这个代码:

public class CtraderClient {
        private final String host;
        private final int port;
        Channel channel = null;

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

        public void run() {
            // Configure the client.
            ClientBootstrap bootstrap = new ClientBootstrap(
                    new NioClientSocketChannelFactory(
                            Executors.newCachedThreadPool(),
                            Executors.newCachedThreadPool()));

            bootstrap.setOption("keepAlive", true);

            HashedWheelTimer timer = new HashedWheelTimer();
            // Configure the pipeline factory.
            bootstrap.setPipelineFactory(new SecurePipelineFactory(timer));

            // Start the connection attempt.
            ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,
                    port));

            // Wait until the connection attempt succeeds or fails.
            channel = future.awaitUninterruptibly().getChannel();
            if (!future.isSuccess()) {
                future.getCause().printStackTrace();
                bootstrap.releaseExternalResources();
                return;
            }

        }
    }

    public class SecurePipelineFactory implements ChannelPipelineFactory {

        private final ChannelHandler idleStateHandler;
        private Timer timer;

        public SecurePipelineFactory(Timer timer) {
            this.timer = timer;
            this.idleStateHandler = new IdleStateHandler(timer, 0, 20, 0); // timer must be shared.
        }

        public ChannelPipeline getPipeline() throws Exception {
            ChannelPipeline pipeline = pipeline();

            SSLContext sslcontext = SSLContext.getInstance("SSL");
            sslcontext.init(null, null, null);
            SSLEngine engine = sslcontext.createSSLEngine();

            engine.setUseClientMode(true);
            SslHandler sslHandler = new SslHandler(engine);

            pipeline.addLast("ssl", sslHandler);


            pipeline.addLast(
                    "frameDecoder",
                    new LengthFieldBasedFrameDecoder(
                            1048576, 0, 4, 0, 4));

            pipeline.addLast("protobufDecoder",
                    new ProtobufDecoder(
                            ProtoMessage.getDefaultInstance()));

            pipeline.addLast("frameEncoder",
                    new LengthFieldPrepender(4));

            pipeline.addLast("protobufEncoder",
                    new ProtobufEncoder());

    //      pipeline.addLast("handler", new SecureHandler());

            pipeline.addLast("protoHandler", new ProtoMessageHandler());

            pipeline.addLast("idleStateHandler", idleStateHandler);

            pipeline.addLast("heartHandler", new HeartbeatHandler());

            return pipeline;
        }

我已经改为这个版本以适应4.0版本:

public class CtraderClient {

        private final String host;
        private final int port;
        Channel channel = null;

        private static final Logger LOGGER = LoggerFactory
                .getLogger(CtraderClient.class);

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

        public void run() throws InterruptedException {
            // Configure the client.
            EventLoopGroup group = new NioEventLoopGroup();
            Bootstrap b = new Bootstrap();
            b.group(group);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.handler(new MyChannelInitializer ());

            // Start the connection attempt.
            ChannelFuture future = b.connect(new InetSocketAddress(host, port))
                    .sync();

            channel = future.awaitUninterruptibly().channel();
            if (!future.isSuccess()) {
                future.cause().printStackTrace();
                //bootstrap.releaseExternalResources();
                return;
            }

        }
        }



        public class MyChannelInitializer extends ChannelInitializer {
        private static final String PROTOCOL = "SSL";

        @Override
           public void initChannel(SocketChannel channel) throws Exception {

                SslHandler sslHandler = createSSLHandler();
                channel.pipeline().addLast("ssl", sslHandler);

                channel.pipeline().addLast(
                        "frameDecoder",
                        new LengthFieldBasedFrameDecoder(
                                1048576, 0, 4, 0, 4));

                channel.pipeline().addLast("protobufDecoder",
                        new ProtobufDecoder(
                                ProtoMessage.getDefaultInstance()));

                channel.pipeline().addLast("frameEncoder",
                        new LengthFieldPrepender(4));

                channel.pipeline().addLast("protobufEncoder",
                        new ProtobufEncoder());

                channel.pipeline().addLast("protoHandler", new ProtoMessageHandler());

                channel.pipeline().addLast("idleStateHandler", new IdleStateHandler(0, 20, 0));

                channel.pipeline().addLast("heartHandler", new HeartbeatHandler());


           }

        private SslHandler createSSLHandler() throws NoSuchAlgorithmException,
                KeyManagementException {

            SSLEngine engine = createSSLEngine();       
            engine.setUseClientMode(true);
            SslHandler sslHandler = new SslHandler(engine);     
            return sslHandler;
        }

        private SSLEngine createSSLEngine() throws NoSuchAlgorithmException,
                KeyManagementException {

            SSLContext sslcontext = SSLContext.getInstance(PROTOCOL);
            sslcontext.init(null, null, null); //SecureTrustManagerFactory.getTrustManagers()  --- I tried it with a dummy
    // x09Trustmanager that returns new X509Certificate[0] in getAcceptedIssuers(), 
    //but I get the same exception
            SSLEngine engine = sslcontext.createSSLEngine();
            return engine;
        }   
    }

有谁知道我做错了什么? Thanx提前!