【问题标题】:How to poll an SSL BIO object? [closed]如何轮询 SSL BIO 对象? [关闭]
【发布时间】:2012-06-13 11:34:45
【问题描述】:

我有一个缓冲 SSL 连接的 BIO 对象。如何轮询连接以查看是否可以在不阻塞的情况下调用读取?

OpenSSL 网站说:

有时与阻塞套接字一起使用的一种技术是使用系统调用(例如 select()、poll() 或等效的)来确定数据何时可用,然后调用 read() 来读取数据。不应使用与 BIO 等效的方法(即在底层 I/O 结构上调用 select(),然后调用 BIO_read() 来读取数据),因为对 BIO_read() 的一次调用可能会导致多次读取(并在SSL BIO 的情况)在底层 I/O 结构上,因此可能会阻塞。取而代之的是 select() (或等效的)应该与非阻塞 I/O 结合使用,因此连续读取将请求重试而不是阻塞。

这里的问题是我无法更改连接的类型,因为它是在其他地方建立的。还有其他方法可以实现我的目标吗?

【问题讨论】:

  • 可以使用 BIO_get_fd() 获取文件描述符,并使用 select() 轮询数据。

标签: c++ windows io openssl


【解决方案1】:

您可能可以使用fcntl(2)F_SETFL 在文件描述符上设置O_NONBLOCK 标志。由于在您想要设置此标志时,套接字正在通过 OpenSSL 的 BIO 实用程序使用,所以应该没问题 - 您的应用程序的其余部分在通过 BIO 例程之前无法使用来自套接字的数据。

因此我相信您可以更改连接类型。

我在 bio.h 标头中看到了一个看起来适合您的情况的 API:

#define BIO_set_nbio(b,n)       BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)

尽管手册中有以下警告:

   BIO_set_nbio() sets the non blocking I/O flag to n. If n is
   zero then blocking I/O is set. If n is 1 then non blocking
   I/O is set. Blocking I/O is the default. The call to
   BIO_set_nbio() should be made before the connection is
   established because non blocking I/O is set during the
   connect process.

也许一旦建立连接,底层 BIO 接口就不会改变;值得尝试明确的fcntl(2) 调用你自己——也许这一切都会正常工作。

【讨论】:

  • 我在 Windows 上,抱歉没有指定。但是,我尝试了 fcntl 的 windows 变体:ioctlsocketOpenSSL 只是崩溃了。
猜你喜欢
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 2020-02-28
  • 2012-12-18
  • 1970-01-01
  • 2014-12-13
相关资源
最近更新 更多