3

私は問題を解決しました。SSLEngineのインスタンスを作成し、それを各clinentリクエストのハンドラーのパイプラインに追加する必要があります。これを行うには、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