很少有文档,高于示例代码中存在的内容,目前可用于Grizzly 2.2,我发现这与SSL实现相关最难以导航。我迫切需要这方面的一些指导。在查看我的代码以确定我需要发布什么以提出完整的问题之后,我意识到首先巩固基础知识可能是最有益的。
以下是Grizzly project提供的三个类,以演示Grizzly的SSL功能的示例实现。除了删除注释之外,代码与2.2.19发布的代码库完全相同,代码库在git中以 git://java.net/grizzly~git 维护,也可用here。
git存储库还提供引用的信任库和密钥库。
public class EchoFilter extends BaseFilter{
@Override
public NextAction handleRead(FilterChainContext ctx)throws IOException {
//|Peer address is used for non-connected UDP Connection
final Object peerAddress = ctx.getAddress();
final Object message = ctx.getMessage();
ctx.write(peerAddress, message, null);
return ctx.getStopAction();
}
}
public class SSLEchoServer{
public static final String HOST = "localhost";
public static final int PORT = 7777;
public static void main(String[] args) throws IOException{
//|Create a FilterChain using FilterChainBuilder
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
//|Add TransportFilter, which is responsible for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());
//|Initialize and add SSLFilter
final SSLEngineConfigurator serverConfig = initializeSSL();
final SSLEngineConfigurator clientConfig = serverConfig.copy().setClientMode(true);
filterChainBuilder.add(new SSLFilter(serverConfig, clientConfig));
//|Add StringFilter, which will be responsible for Buffer <-> String transformation
filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
//|Use the plain EchoFilter
filterChainBuilder.add(new EchoFilter());
//|Create TCP transport
final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
//|Set filterchain as a Transport Processor
transport.setProcessor(filterChainBuilder.build());
try{
//|Binding transport to start listen on certain host and port
transport.bind(HOST, PORT);
//|Start the transport
transport.start();
System.out.println("Press any key to stop the server...");
System.in.read();
}finally{
System.out.println("Stopping transport...");
//|Stop the transport
transport.stop();
System.out.println("Stopped transport...");
}
}
private static SSLEngineConfigurator initializeSSL(){
//|Initialize SSLContext configuration
SSLContextConfigurator sslContextConfig = new SSLContextConfigurator();
//|Set key store
ClassLoader cl = SSLEchoServer.class.getClassLoader();
URL cacertsUrl = cl.getResource("ssltest-cacerts.jks");
if(cacertsUrl != null){
sslContextConfig.setTrustStoreFile(cacertsUrl.getFile());
sslContextConfig.setTrustStorePass("changeit");
}
//|Set trust store
URL keystoreUrl = cl.getResource("ssltest-keystore.jks");
if(keystoreUrl != null){
sslContextConfig.setKeyStoreFile(keystoreUrl.getFile());
sslContextConfig.setKeyStorePass("changeit");
}
//|Create SSLEngine configurator
return new SSLEngineConfigurator(sslContextConfig.createSSLContext(), false, false, false);
}
}
public class SSLEchoClient{
private static final String MESSAGE = "Hello World!";
public static void main(String[] args) throws IOException{
//|Create a FilterChain using FilterChainBuilder
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
//|Add TransportFilter, which is responsible for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());
//|Initialize and add SSLFilter
final SSLEngineConfigurator serverConfig = initializeSSL();
final SSLEngineConfigurator clientConfig = serverConfig.copy().setClientMode(true);
final SSLFilter sslFilter = new SSLFilter(serverConfig, clientConfig);
filterChainBuilder.add(sslFilter);
//|Add StringFilter, which will be responsible for Buffer <-> String transformation
filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
//|Add Filter, which will send a greeting message and check the result
filterChainBuilder.add(new SendMessageFilter(sslFilter));
//|Create TCP transport
final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
//|Set filterchain as a Transport Processor
transport.setProcessor(filterChainBuilder.build());
try{
//|Start the transport
transport.start();
//|Perform async. connect to the server
transport.connect(SSLEchoServer.HOST, SSLEchoServer.PORT);
System.out.println("Press any key to stop the client...");
System.in.read();
}finally{
System.out.println("Stopping transport...");
//|Stop the transport
transport.stop();
System.out.println("Stopped transport...");
}
}
private static class SendMessageFilter extends BaseFilter{
private final SSLFilter sslFilter;
public SendMessageFilter(SSLFilter sslFilter){
this.sslFilter = sslFilter;
}
@Override
@SuppressWarnings("unchecked")
public NextAction handleConnect(FilterChainContext ctx) throws IOException{
final Connection connection = ctx.getConnection();
//|Execute async SSL handshake
sslFilter.handshake(connection, new EmptyCompletionHandler<SSLEngine>(){
//|Once SSL handshake will be completed - send greeting message
@Override
public void completed(SSLEngine result){
//|Here we send String directly
connection.write(MESSAGE);
}
});
return ctx.getInvokeAction();
}
@Override
public NextAction handleRead(FilterChainContext ctx) throws IOException{
//|The received message is String
final String message = (String) ctx.getMessage();
//|Check the message
if(MESSAGE.equals(message)){
System.out.println("Got echo message: \"" + message + "\"");
}else{
System.out.println("Got unexpected echo message: \"" + message + "\"");
}
return ctx.getStopAction();
}
}
private static SSLEngineConfigurator initializeSSL(){
//|Initialize SSLContext configuration
SSLContextConfigurator sslContextConfig = new SSLContextConfigurator();
//|Set key store
ClassLoader cl = SSLEchoClient.class.getClassLoader();
URL cacertsUrl = cl.getResource("ssltest-cacerts.jks");
if(cacertsUrl != null){
sslContextConfig.setTrustStoreFile(cacertsUrl.getFile());
sslContextConfig.setTrustStorePass("changeit");
}
//|Set trust store
URL keystoreUrl = cl.getResource("ssltest-keystore.jks");
if(keystoreUrl != null){
sslContextConfig.setKeyStoreFile(keystoreUrl.getFile());
sslContextConfig.setKeyStorePass("changeit");
}
//|Create SSLEngine configurator
return new SSLEngineConfigurator(sslContextConfig.createSSLContext(), false, false, false);
}
}
运行SSLEchoServer:
按任意键停止服务器......
运行SSLEchoClient:
按任意键停止客户端...
这段代码应该完成或演示什么?除了上面提到的控制台输出之外,这段代码在我的最后没有任何作用。
在审查代码时,我的期望是客户端应该启动其TCP传输并将其连接到服务器。在建立连接的过程中,先前添加到过滤器流的 SendMessageFilter 将执行其 handleConnect()方法,我确认该方法已执行。但是,此代码从不执行 connection.write(MESSAGE)语句。
很明显,这里的意图是在握手线程完成后执行 write()方法,但它似乎没有这样做,并且在检查 handshake()< grizzly-framework-2.2.19中的SSLFilter类中的/ em>方法,我也无法确定甚至已定义被覆盖的父 completed()方法的位置。
任何人都可以了解这种脱节是否是由于我对此缺乏了解或者是否可能是Grizzly提供的示例实施中的错误?我相信清除这一点将大大有助于我在这里进一步理解。提前谢谢!