2015-06-23 2 views
1

Я хочу сделать неблокирующее соединение OpenSSLКак сделать неблокирующее соединение OpenSSL?

В этом соединении - если данные не доступны для чтения, то весь поток выполнения программы останавливается на SSL_read(). Я хочу, чтобы, если никакие данные для чтения не дали мне значений возвращаемых значений, таких как 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; 

}

вот как я установить соединение

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

благодарит вас очень много.

+0

Потому что мне нужно было добавить некоторые ссылки. Сожалею. – ryyker

+0

не проблема, я пробовал это сейчас и отчитываюсь за вас. – MrTall394

+0

Возможный дубликат [Неблокирование подключения OpenSSL] (http://stackoverflow.com/questions/23232780/non-blocking-connect-openssl) и [Изменение OpenSSL BIO от блокировки до неблокирующего режима] (http://stackoverflow.com/q/8411168). – jww

ответ

2

Создание нелипкой сокеты является предварительным условием для неблокирующая подключении ...

Следующих шагов кратко: (см полного описания на сайте связанного ниже)

1) Вызовите API fcntl(), чтобы получить текущие настройки флагов дескриптора сокета в локальную переменную.

2) В нашей локальной переменной, установить (без блокировки) флаг O_NONBLOCK дальше. (Быть осторожным, конечно, не возиться с другими флагами)

3) Вызвать FCNTL() API для установки флагов дескриптора к значению в нашей локальной переменной.

(read more on non-blocking sockets techniques here)

Предполагая, что существующий разъем, следующий реализует шаги, описанные выше:

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 
} 

После того, как у вас есть нелипкая сокет, то см this post объяснить, как сделать неблокирующее соединение

Смежные вопросы