2

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

OpenSSL 网站说:

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

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

4

1 回答 1

0

您可能可以使用fcntl(2)'s在文件描述符上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)——也许这一切都会正常工作。

于 2012-06-09T23:48:27.223 回答