c++ - 非阻塞连接 OpenSSL

标签 c++ c sockets openssl

我创建了一个常规的 C 套接字。连接后,它按预期返回 EWOULDBLOCK/WSAEWOULDBLOCK 因为我做了:

unsigned long int mode = 0;
ioctlsocket(ssl_info->sock, FIONBIO, &mode);
setsockopt(ssl_info->sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));
setsockopt(ssl_info->sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));

将套接字置于非阻塞模式。之后我会:

ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
return SSL_connect(ssl);

但是,它返回 -1。

我在网上看到这意味着我需要处理 SSL_ERROR_WANT_READSSL_ERROR_WANT_WRITE

我这样做了:

int res = -1;
while(res == -1)
{
    res = SSL_connect(ssl);
    switch (SSL_get_error(ssl, res))
    {
        case SSL_ERROR_WANT_CONNECT:
        MessageBox(NULL, "Connect Error", "", 0);
        break;

        case SSL_ERROR_WANT_READ:   //prints this every time..
        MessageBox(NULL, "Read Error", "", 0);
        break;

        case SSL_ERROR_WANT_WRITE:
        MessageBox(NULL, "Write Error", "", 0);
        break;
    }

    SelectSocket(ssl);
}

std::cout<<"Connected!\n";

其中 SelectSocket 定义为:

bool SelectSocket(SSL* ssl)
{
    if (blockmode)
    {
        fd_set readfds;
        fd_set writefds;
        FD_ZERO(&readfds);
        FD_ZERO (&writefds);
        FD_SET(ssl_info->sock, &readfds);
        FD_SET(ssl_info->sock, &writefds);

        struct timeval tv = {0};
        tv.tv_sec = timeout / 1000;
        tv.tv_usec = timeout % 1000;
        return select(sock + 1, &readfds, &writefds, NULL, &tv) >= 0;
    }

    return select(sock + 1, NULL, NULL, NULL, NULL) != SOCKET_ERROR;
}

那么我怎样才能让它连接呢?当套接字是非阻塞时,我似乎无法读取或写入任何内容:S。

有什么想法吗?

最佳答案

SSL_connect()返回的(-1)表示底层BIO不能满足SSL_connect()继续握手的需要。

通常,调用进程必须在采取适当的操作以满足 SSL_connect() 的需要后重复调用。

然而,当使用非阻塞套接字时,什么都不用做;但 select() 可用于检查所需条件。

(使用缓冲 BIO 时,如 BIO 对,必须先将数据写入 BIO 或从 BIO 中检索数据,然后才能继续。)

关于c++ - 非阻塞连接 OpenSSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23232780/

相关文章:

c++ - Google C++ 风格指南中提到的对象所有者是什么?

c++ - 如果未定义析构函数,为什么不进行返回值优化?

c - 如何让strcmp在汇编中返回0

c - 打印二维数组会打印垃圾(Magic Square)

c - 如何仅使用指针重写这个 strcpy() 函数?

c++ - 在类内或类外访问时输出相同变量但输出不同

c++ - 在 Mac OS X(10.11) 上安装 opencv(3.1.0) 时出错

c - 在C中的代理服务器中转发GET请求

linux - 为什么非阻塞 TCP connect() 在 Linux 上偶尔会这么慢?

无法在 C Fedora16 中关闭非阻塞 UDP 套接字