在互联网上所有的 NIO2 的来源/示例都没有TLS/SSL支持,我理解 SSLEngine 连接生命周期与 AsynchronousSocketChannel.connect && AsynchronousServerSocketChannel.accept 不同。TLS/SSL应该封装在AIO实现内部,那么我该如何同时使用它们呢?注意:我在 Grizzly 项目中看到了一个视频,谈论他们已经实现了它,我看了源代码,但只看到了AIO而没有TLS/SSL集成...提前感谢!
原问题的评论确实是正确的。SSLEngine 直接使用 ByteBuffer 进行操作。这意味着它与AIO兼容。您首先接受连接。然后客户端连接并执行初始写入。要确定是否有足够的数据缓冲,请使用握手状态和状态。如果需要从另一端提供更多数据,则引擎将继续告诉您“NEED_UNWRAP”。因此,您需要保留ByteBuffer对象的队列。同样,如果需要在继续之前向另一端发送更多数据,则引擎将继续告诉您“NEED_WRAP”。您需要继续进行,直到从握手状态获得“完成”。然而,我建议您使用像Netty这样的工具,这将使此过程变得更加简单。值得注意的是,在4的alpha阶段中,Netty确实支持AIO。但是,AIO比NIO更慢,因此被移除了。然而,Netty不仅会使事情比直接使用NIO或AIO更简单,而且还会使在需要重新引入AIO时轻松切换两者变得容易。使用Netty进行SSL的完整示例可以在此处找到。
在Java中进行TLS的标准方法是使用SSLEngine。但是那个类非常难用。虽然有一些教程,但对于典型应用程序来说,使用SSLEngine应该不在考虑范围内。ByteChannel及其相关类没有直接支持,并且意味着需要大量工作。我曾经遇到过同样的问题,最终编写了自己的库。有一些示例和当然还有像Netty等项目中的代码。但是这两种选择都不够强大或易于重用。 TLS Channel将SSLEngine包装在ByteBuffer中,并允许像普通SocketChannels一样使用它。AsynchronousByteChannels是一个高级抽象层,隐藏了选择器循环;该库也支持此功能。