在Java中,SSLSocket API上的写入操作是阻塞的,写入操作也不支持超时。
有人可以解释一下吗?
- 是否存在写入操作可以永久阻塞线程的情况?我检查了互联网,似乎有可能永远阻止。
- 如何为写入操作添加超时?
我的应用程序创建两个线程,一个用于读取,一个用于写入。
1-是否存在写入操作可以永久阻塞线程的情况?我检查了互联网,似乎有可能永远阻止。
是的,可以。 虽然不是永远:-(
2-有人可以建议我们如何为写入操作添加超时吗?
你不能用Java的套接字/SSL套接字等实现来做到这一点。 Java 套接字支持连接超时和读取超时,但不支持写入超时。
另请参阅:如何在 java 中设置套接字写入时间?
(为什么? 早在 1997 年,错误 ID JDK-4031100 中就请求了套接字写入超时,但该错误以状态"WontFix"关闭。 有关详细信息,请阅读链接。
替代方案包括:
-
使用计时器实现超时,并在计时器关闭时中断线程或关闭套接字。 请注意,中断和关闭都会使您处于需要放弃套接字的状态。
-
使用 NIO 选择器和非阻塞 I/O。
因为:
- 如果需要这样的工具,则需要在TCP级别,而不仅仅是SSL级别。 在
- TCP级别没有API,我的意思不仅仅是在Java中:也没有C级API,除了几个平台。 如果在 SSL 级别添加它,
- 写入超时事件将使连接处于不确定状态,这意味着它必须关闭,因为您无法知道传输了多少数据,因此您无法在 SSL 级别保持完整性。
要解决您的具体问题,请执行以下操作:
- 是否存在写入操作可以永久阻塞线程的情况?我检查了互联网,似乎有可能永远阻止。
是的。在这种情况下,我看到一个应用程序被阻止了几天。虽然不是,正如@StephenC正确所说,永远。我们还没有活那么久。
- 如何为写入操作添加超时?
您可以使用非阻塞I/O和Selector
在TCP级别执行此操作,并且可以在此之上分层SSLEngine
以获取SSL,但是这是一项乏味且非常容易出错的练习,许多人都尝试过:很少有人成功。不适合胆小的人。