与SSL的Netty Server连接在调用后丢弃客户端连接

时间:2016-10-25 14:22:02

标签: sockets netty

我正在使用ssl运行Netty 4.2套接字通信代码(自签名证书)。

我的问题: 当客户端尝试使用SSL连接到服务器时,服务器会立即断开连接。服务器立即触发channelUnregistered()方法。

我注意到的一点是,一旦服务器启动,第一次客户端连接保持并正常工作。但是当客户端断开连接并尝试再次连接到服务器时,它会立即断开连接。

但如果没有SSL,它可以正常工作而没有任何问题。

客户代码:

public Channel initializeNettySocket()
{
    group = new NioEventLoopGroup();
    try
    {
        ClientAdapterInitializer clientAdapterInitializer = null;
        if (ServerSettings.isUseSSL())
        {
            //              SSLEngine engine = SSLContextFactory.getClientContext().createSSLEngine();
            SSLEngine engine = SSLContext.getDefault().createSSLEngine(host,port);
            engine.setUseClientMode(true);
            clientAdapterInitializer = new ClientAdapterInitializer(engine);
        }
        else
        {
            clientAdapterInitializer = new ClientAdapterInitializer();
        }

        Bootstrap bootstrap = new Bootstrap().group(group).channel(NioSocketChannel.class).handler(clientAdapterInitializer);

        channel = bootstrap.connect(host,port).sync().channel();
        Thread.sleep(3000);

        setChannel(channel);
    }
    catch (Exception e)
    {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
    return channel;
}

  public class ClientAdapterInitializer extends ChannelInitializer<SocketChannel>

{

private SSLEngine sslCtx = null;

public ClientAdapterInitializer(SSLEngine sslCtx)
{
    this.sslCtx = sslCtx;
}

public ClientAdapterInitializer()
{
}

@Override
protected void initChannel(SocketChannel channel) throws Exception
{
    ChannelPipeline pipeline = channel.pipeline();

    if (ServerSettings.isUseSSL())
    {
        // Add SSL handler first to encrypt and decrypt everything.
        // In this example, we use a bogus certificate in the server side
        // and accept any invalid certificates in the client side.
        // You will need something more complicated to identify both
        // and server in the real world.
        //pipeline.addLast(sslCtx.newHandler(ch.alloc(), SecureChatClient.HOST, SecureChatClient.PORT));
        pipeline.addLast(new SslHandler(sslCtx));
    }
    pipeline.addLast("decoder", new StringDecoder());
    pipeline.addLast("encoder", new StringEncoder());
    pipeline.addLast("handler", new ClientAdapterHandler());

}

服务器端代码

public class ServerAdapterInitializer extends ChannelInitializer<SocketChannel>

{

private SSLEngine sslEngine;

public ServerAdapterInitializer(SSLEngine sslEngine)
{
    this.sslEngine = sslEngine;
}

public ServerAdapterInitializer()
{
}

@Override
protected void initChannel(SocketChannel channel) throws Exception
{
    ChannelPipeline pipeline = channel.pipeline();
    if (sslEngine != null)
    {
        pipeline.addLast(new SslHandler(sslEngine));
    }
    Listeners.getInstance().getAllListeners().size();
    RTReceiverAdapterHandler rtReceiverAdapterHandler = new RTReceiverAdapterHandler();
    pipeline.addLast("idleStateHandler", new IdleStateHandler(0, 0, 10)); // add
                                                                            // with
                                                                            // name
    pipeline.addLast("decoder", new MyStringDecoder(rtReceiverAdapterHandler));
    pipeline.addLast("encoder", new StringEncoder());

    pipeline.addLast("handler", rtReceiverAdapterHandler);
}

}

public class RTReceiverAdapterHandler extends ChannelInboundHandlerAdapter
{
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception
{
    if (ServerSettings.isUseSSL())
    {
        // Once session is secured, send a greeting and register the channel
        // to the global channel
        // list so the channel received the messages from others.
        ctx.pipeline().get(SslHandler.class).handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>()
        {
            @Override
            public void operationComplete(Future<Channel> future) throws Exception
            {
                ctx.writeAndFlush("Welcome!\n");
                ctx.writeAndFlush("Your session is protected by " + ctx.pipeline().get(SslHandler.class).engine().getSession().getCipherSuite()
                        + " cipher suite.\n");
                channels.add(ctx.channel());
            }
        });
    }
    else
    {
        super.channelActive(ctx);
    }
}

}

1 个答案:

答案 0 :(得分:0)

问题不在于代码。我的应用程序之前配置了SSL的nginx Web服务器。此条目在nginx&#39; ssl_ciphers AES256 + EECDH:AES256 + EDH:!aNULL;&#39;是不允许访问netty服务器的罪魁祸首。

我评论了ngnix中的上述条目,我的问题得到了解决。