如何判断Java SSLSocket是否有数据可用?

时间:2014-10-12 00:26:13

标签: java sockets ssl

当我使用常规套接字时,我可以调用getInputStream()并使用available()来查看可用的字节数。我切换到SSLSocket,但现在available()总是因某种原因返回0。当我阅读时,我仍然可以获得数据。如何判断SSLSocket中是否有可用的数据,以便在没有数据的情况下可以不加阻断地为其提供服务?

注意:

  • 我无法在InputStream上调用read()或线程将阻塞。我想在我的实现中进行非阻塞。
  • available()返回0,即使有SSLSocket的InputStream数据。

2 个答案:

答案 0 :(得分:4)

我认为你解决了问题,但对于像我这样的人,我找到了一个更简单的解决方案。如果执行读取,则available()方法将填充解密的内容。如何使用和滥用这个?读取套接字上SoTimeout非常低的单个字节,如果捕获到SocketTimeoutException,则连接为空,如果没有,则将读取的字节添加到将来对消息的解释中。直到in.available()== 0再次,只需滚动它。

答案 1 :(得分:2)

没有办法做到这一点。如果没有先解密,您的流无法告诉您数据的长度。 available()总是SSLSocket返回0。

this chat中所述,您要检查数据的原因是为了防止read()在被调用时被阻止,因此您可以在单个线程上处理多个连接,而不是每个客户端的线程系统。

相反,请使用非阻塞替代方案。 java.nio目前还没有自己的SocketChannel SSL实施,但您可以在线找到(例如here)或创建自己的SSL。

使用此系统,您可以向每个频道注册Selector,并使用"选择器线程"进行全部管理。我写了一个如何使用选择器here的示例(向下滚动到使用选择器)。

使用非阻塞IO,您可以为每个线程处理多个客户端,从而可以扩展。由于C10k Problem

,这种管理渠道的方法已经提出