简体   繁体   English

非阻塞连接OpenSSL

[英]Non-blocking connect OpenSSL

I created a regular C socket. 我创建了一个常规的C套接字。 Upon connect, it returns EWOULDBLOCK/WSAEWOULDBLOCK as expected because I did: 连接后,它按预期返回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));

to put the socket in non-blocking mode. 将套接字置于非阻塞模式。 After that I do: 之后,我要做:

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

However, it returns -1. 但是,它返回-1。

I read online that it means I need to handle SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE . 我在网上阅读这意味着我需要处理SSL_ERROR_WANT_READSSL_ERROR_WANT_WRITE

so I did: 所以我做了:

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";

Where SelectSocket is defined as: 其中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;
}

So how exactly can I get it to connect? 那么我如何才能使其连接呢? I can't seem to be able to read or write anything when the socket is non-blocking :S. 当套接字是非阻塞的:S时,我似乎无法读取或写入任何内容。

Any ideas? 有任何想法吗?

The (-1) returned by SSL_connect() indicates that the underlying BIO could not satisfy the needs of SSL_connect() to continue the handshake. SSL_connect()返回的(-1)表示基础BIO无法满足SSL_connect()继续握手的需求。

Generally, the calling process then must repeat the call after taking appropriate action to satisfy the needs of SSL_connect(). 通常,调用过程然后必须采取适当的措施以满足SSL_connect()的需要后重复该调用。

However, when using a non-blocking socket, nothing is to be done; 但是,当使用非阻塞套接字时,什么也不做; but select() can be used to check for the required condition. 但是select()可用于检查所需条件。

(When using a buffering BIO, like a BIO pair, data must be written into or retrieved out of the BIO before being able to continue.) (当使用缓冲BIO(如BIO对)时,必须先将数据写入BIO或从中检索出数据,然后才能继续。)

Your code actually disables non-blocking I/O. 您的代码实际上禁用了非阻塞I / O。 As you are passing 0 as argument value for FIONBIO to ioctlsocket, which is documented as: 当您将0作为FIONBIO的参数值传递给ioctlsocket时,记录为:

FIONBIO 菲奥比奥

The *argp parameter is a pointer to an unsigned long value. * argp参数是一个指向无符号long值的指针。 Set *argp to a nonzero value if the nonblocking mode should be enabled , or zero if the nonblocking mode should be disabled . 如果应启用 非阻塞模式,则将* argp设置为非零值;如果应禁用非阻塞模式,则将* argp设置为零 [..] [..]

https://msdn.microsoft.com/en-us/library/windows/desktop/ms738573%28v=vs.85%29.aspx https://msdn.microsoft.com/zh-CN/library/windows/desktop/ms738573%28v=vs.85%29.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM