Select 用于非阻塞套接字的SSL_连接

Select 用于非阻塞套接字的SSL_连接,select,openssl,nonblocking,Select,Openssl,Nonblocking,我使用非阻塞套接字。对于正常的TCP连接,我执行以下操作: 但是对于SSL_connect调用,我无法让它工作 我理解它,因为我应该: 1.反复调用SSL\u connect。 2.检查SSL\u get\u error是SSL\u error\u WANT\u READ还是SSL\u error\u WANT\u WRITE。 3.如果是这样的话,那么我无法100%确定下一步该怎么办。我应该打电话给SSL_connect吗,直到我没有收到?或者我应该像使用普通套接字一样,使用select u

我使用非阻塞套接字。对于正常的TCP连接,我执行以下操作:

但是对于SSL_connect调用,我无法让它工作

我理解它,因为我应该: 1.反复调用SSL\u connect。 2.检查SSL\u get\u error是SSL\u error\u WANT\u READ还是SSL\u error\u WANT\u WRITE。 3.如果是这样的话,那么我无法100%确定下一步该怎么办。我应该打电话给SSL_connect吗,直到我没有收到?或者我应该像使用普通套接字一样,使用select using read_fds或write_fds检查套接字,并使用FD_ISSET检查,如果是,则使用so_ERROR检查getsockopt

基本上,对于SSL_connect和非阻塞套接字,什么告诉我连接成功了? 我已经看过其他的例子,但没有一个是足够清楚的。

这里有一个算法:

int s = socket(...);
fcntl(s, ...); // make it non-blocking
while (-1 == connect(s,...))
{
   fd_set fds;
   FD_ZERO(&fds);
   FD_SET(s, &fds);
   select(s + 1, NULL, &fds, NULL, NULL);
}

... // initialize all SSL stuff
SSL_set_fd(ctx, s);
while (-1 == SSL_connect(ssl))
{
   fd_set fds;
   FD_ZERO(&fds);
   FD_SET(s, &fds);

   switch (SSL_get_error())
   {
   case SSL_ERROR_WANT_READ:
       select(s + 1, &fds, NULL, NULL, NULL);
       break;
   case SSL_ERROR_WANT_WRITE:
       select(s + 1, NULL, &fds, NULL, NULL);
       break;
   default: abort();
   }
}
// done...

下面是一个将非阻塞套接字与内存bios结合使用的方法示例。非阻塞IO用于填充内存BIO,只有当轮询循环表明IO调用不会阻塞时,才会进行IO调用


您的猜测是对的:您应该根据操作结果使用
poll
select
api等待合适的套接字事件。然后重复操作。但我应该只调用一次SSL_connect吗?我在用select等待什么?如果为我的套接字设置了读或写,这意味着什么?我该怎么办?我是否调用getsockopt?通常您会给
SSL\u connect
提供一个已连接的套接字。此功能不是用于较低级别的连接操作,而是用于安全协议设置。是的,我知道。我可以使用阻塞套接字进行SSL_连接。但我不确定非阻塞的。我需要一些用于整个过程的伪代码。Ty但是我不理解select调用的意义。它实现了什么。?如果出现错误或SSL_connect!=-1.select调用添加了什么?
select
阻塞执行,直到套接字变为可读写。也就是说,网络缓冲区中有数据可以从远程对等方读取,或者输出缓冲区中有可用空间可以发送。我无法阻止,这就是我使用非阻止套接字的原因。我能做的就是反复调用SSL\u connect并在其间执行其他操作,是否可以只调用SSL\u connect直到它连接或出现错误?除了等待之外,select调用没有其他意义?只要事件循环为空,您就应该阻塞它。也就是说,当它无事可做时。若您只是重复调用函数,那个么您将过度使用CPU资源。或者,如果您可以不时调用它,它也会以某种方式工作,但只会产生额外的内核调用。好的,但要明确的是,所需要的只是轮询SSL\u connect,直到它成功或失败,并出现另一个错误,而不是希望读取或写入?