我正在使用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);
}
}
}
答案 0 :(得分:0)
问题不在于代码。我的应用程序之前配置了SSL的nginx Web服务器。此条目在nginx&#39; ssl_ciphers AES256 + EECDH:AES256 + EDH:!aNULL;&#39;是不允许访问netty服务器的罪魁祸首。
我评论了ngnix中的上述条目,我的问题得到了解决。