3

我已经解决了这个问题。您需要创建一个 SSLEngine 实例并将其添加到每个客户端请求的处理程序管道中。我通过在 channelConnected 事件中添加处理程序并在断开连接的通道中删除 ssl 处理程序来完成此操作。这确保每个连接的通道都将被添加新的。

下面是处理程序的代码。这是使用 SSL 支持进行持久套接字连接的正确方法吗?

package server;
import static org.jboss.netty.buffer.ChannelBuffers.dynamicBuffer;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.handler.ssl.SslHandler;
import ssl.SslContextFactory;
import ssl.SslKeyStore;

public class ServerHandler extends SimpleChannelHandler {
  private static final String ECHORES   = "0057081082200000000000000400000000000000070612201399966400301";
  @Override
  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
System.out.println("Inside ServerHandler.messageReceived");
ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
ChannelBuffer temp = dynamicBuffer();
temp.writeBytes(buffer);
if (temp.readableBytes() >= 4) {
   byte messageLen[] = new byte[4];
   temp.readBytes(messageLen);
   int len = Integer.parseInt(new String(messageLen));
   System.out.println("Length of the message is : " + len);
   if (temp.readableBytes() >= len) {
       byte[] message = new byte[len];
       temp.readBytes(message);
       System.out.println("Input message is : " + new String(message));
       Channel channel = e.getChannel();
       buffer = ChannelBuffers.copiedBuffer(ECHORES.getBytes());
       ChannelFuture future = channel.write(buffer);
       future.addListener(ChannelFutureListener.CLOSE);
   }
}
     }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
e.getCause().printStackTrace();
Channel channel = e.getChannel();
channel.close();
 }

 @Override
 public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
String file = "test.jks";
SSLContext sslCtx = SslContextFactory.getServerContext(new SslKeyStore(file));
final SSLEngine sslEngine =sslCtx.createSSLEngine();
sslEngine.setNeedClientAuth(false);
sslEngine.setUseClientMode(false);
final SslHandler sslHandler = new SslHandler(sslEngine);
ctx.getPipeline().addFirst("ssl", sslHandler);
ChannelFuture handshakeFuture = sslHandler.handshake();
handshakeFuture.addListener(new ChannelFutureListener() {

    @Override
    public void operationComplete(ChannelFuture future) throws Exception {
       if (future.isSuccess()) {
         System.out.println("SSL/TLS session established");
         System.out.println("Your session is protected by "+ sslHandler.getEngine().    
                         getSession().getCipherSuite() + " cipher suite.\n");
       } else {
           future.getChannel().close();
       }
    }
});
    }

    @Override
    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("Inside ServerHandler.channelDisconnected");
ctx.getPipeline().remove("ssl");
    }
}

使用带有 ssl 的 netty 时出现以下异常。我的第一笔交易和握手都很顺利。如果我再次向服务器发送新消息,我会收到此异常。

“javax.net.ssl.SSLException:SSLEngine 正在关闭/关闭”

这里可能出了什么问题。如何保持已建立的 TLS/SSL 会话?这个错误发生在 org.jboss.netty.handler.ssl.SslHandler.handshake(SslHandler.java:358)。

目的是让服务器使用持久的 TLS 套接字连接运行,以便客户端可以发送消息。

-TK

4

0 回答 0