简体   繁体   English

如何进行非阻塞 OpenSSL 连接?

[英]How to make non-blocking OpenSSL connection?

I want make a non-blocking OpenSSL connection我想建立一个非阻塞的 OpenSSL 连接

On this connection - if no data available for read, then entire program execution flow make stop on SSL_read().在此连接上 - 如果没有可供读取的数据,则整个程序执行流程会在 SSL_read() 上停止。 I want so that if no data available for read it give me the returns values like WANT_READ and i know no more data available.我想要这样,如果没有可供读取的数据,它会给我像 WANT_READ 这样的返回值,我知道没有更多的数据可用。

char *sslRead (connection *c)
{
const int readSize = 1024;
char *rc = NULL;
int r;
int received, count = 0;
int ReallocSize = 0;
char buffer[1024];

if (c)
{
    while (1)
    {
        if (!rc)
        {
            rc = malloc (readSize + 1); 
            if (rc == NULL)
                printf("the major error have happen. leave program\n");
        }
        else
        {
            ReallocSize = (count + 1) * (readSize + 1);
            rc = realloc (rc, ReallocSize);
        }

        // if i have no data available for read after reading data, 
        // this call will not return anything and wait for more data

        // i want change this non blocking connections
        received = SSL_read (c->sslHandle, buffer, readSize);

        buffer[received] = '\0';


        if (received <= 0)
        {
            printf(" received equal to or less than 0\n");
            switch (SSL_get_error(c->sslHandle, r))
            {
            case SSL_ERROR_NONE:
                printf("SSL_ERROR_NONE\n");
                break;   
            case SSL_ERROR_ZERO_RETURN: 
                printf("SSL_ERROR_ZERO_RETURN\n");
                break;   
            case SSL_ERROR_WANT_READ: 
                printf("SSL_ERROR_WANT_READ\n");
                break;
            default:
                printf("error happens %i\n", r); 
            }     
            break;
        }

        count++;
    }
}
return rc;

} }

here is how i make connection这是我建立联系的方式

connection *sslConnect (void)
{
   connection *c;

   c = malloc (sizeof (connection));
   c->sslHandle = NULL;
   c->sslContext = NULL;

   c->socket = tcpConnect ();
   if (c->socket)
   {
    // Register the error strings for libcrypto & libssl
    SSL_load_error_strings ();
    // Register the available ciphers and digests
    SSL_library_init ();

    // New context saying we are a client, and using SSL 2 or 3
    c->sslContext = SSL_CTX_new (SSLv23_client_method ());
    if (c->sslContext == NULL)
    ERR_print_errors_fp (stderr);

    // Create an SSL struct for the connection
    c->sslHandle = SSL_new (c->sslContext);
    if (c->sslHandle == NULL)
    ERR_print_errors_fp (stderr);

    // Connect the SSL struct to our connection
    if (!SSL_set_fd (c->sslHandle, c->socket))
    ERR_print_errors_fp (stderr);

    // Initiate SSL handshake
    if (SSL_connect (c->sslHandle) != 1)
    ERR_print_errors_fp (stderr);
    }
    else
    {
     perror ("Connect failed");
    }

    return c;
}

thanks you very much.非常感谢你。

Creating a non-blocking socket is a pre-requisite to a non-blocking connect...创建非阻塞套接字是非阻塞连接的先决条件...

The following steps summarize: (see complete description in site linked below)以下步骤总结:(请参阅下面链接的站点中的完整说明)

1) Call the fcntl() API to retrieve the socket descriptor's current flag settings into a local variable. 1)调用 fcntl() API 将套接字描述符的当前标志设置检索到局部变量中。

2) In that local variable, set the O_NONBLOCK (non-blocking) flag on. 2)在该局部变量中,设置 O_NONBLOCK(非阻塞)标志。 (being careful not to tamper with the other flags) (注意不要篡改其他标志)

3) Call the fcntl() API to set the flags for the descriptor to the value in our local variable. 3)调用 fcntl() API 将描述符的标志设置为我们本地变量中的值。

( read more on non-blocking sockets techniques here ) 在此处阅读有关非阻塞套接字技术的更多信息

Assuming an existing socket, the following implements the steps outlined above:假设一个现有的套接字,以下实现上述步骤:

BOOL SetSocketBlockingEnabled(SOCKET fd, BOOL blocking)
{
     if (fd < 0) return FALSE;  
   #ifdef WIN32
       unsigned long mode = blocking ? 0 : 1;
       return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? TRUE : FALSE;
   #else
       int flags = fcntl(fd, F_GETFL, 0);
       if (flags < 0) return false;
       flags = blocking ? (flags&~O_NONBLOCK) : (flags|O_NONBLOCK);
       return (fcntl(fd, F_SETFL, flags) == 0) ? TRUE : FALSE;
   #endif
}

Once you have a non-blocking socket, then see this post explaining how to do a non-blocking connect一旦你有一个非阻塞套接字,然后看这篇文章解释如何做一个非阻塞连接

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

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