为什么 SSLSocket 写入选项没有超时?

Why SSLSocket write option does not have timeout?

在Java中,对SSLSocket API的写操作是阻塞的,写操作也不支持超时。

有人可以解释一下吗?

  1. 会不会出现写操作永远阻塞线程的情况?我上网查了一下,好像有永远屏蔽的可能。
  2. 如何为写操作添加超时?

我的应用程序创建了两个线程,一个用于读取,一个用于写入。

1- Can there be a situation where write operation can block a thread forever? I checked on Internet and it seems that there is a possibility of blocking forever.

可以。虽然不是字面上的永远:-)

2- Can someone please suggest how we can add timeout for write operation?

您无法使用 Java 的套接字/SSL 套接字等实现。 Java 套接字支持连接超时和读取超时但不支持写入超时。

另请参阅:

(为什么?在 1997 年的错误 ID JDK-4031100 中请求套接字写入超时,但错误已关闭,状态为 "WontFix"。阅读 link 了解详细信息。)

备选方案包括:

  1. 使用Timer实现超时,如果定时器超时则中断线程或关闭Socket。请注意,中断和关闭都会使您处于需要放弃套接字的状态。

  2. 使用 NIO 选择器和非阻塞 I/O。

因为:

  1. 如果需要这样的设施,则需要在 TCP 级别,而不仅仅是 SSL 级别。
  2. 在 TCP 级别没有 API,我的意思不是只在 Java 中:也没有 C 级别 API,除了也许在几个平台上。
  3. 如果您在 SSL 级别添加它,写超时事件会使连接处于不确定状态,这意味着它必须关闭,因为您不知道传输了多少数据,所以您无法在 SSL 级别保持完整性。

解决您的具体问题:

  1. Can there be a situation where write operation can block a thread forever? I checked on Internet and it seems that there is a possibility of blocking forever.

是的。在这种情况下,我已经看到一个应用程序被阻止了好几天。虽然不是,正如@StephenC 正确地说的那样,永远。我们还没有活那么久。

  1. How to add timeout for write operation?

您可以在 TCP 级别使用非阻塞 I/O 和 Selector,并且您可以在其之上分层 SSLEngine 以获得 SSL,但是它是一项繁琐且极易出错的练习,许多人都尝试过:很少有人成功。不适合胆小的人。