2014-05-07 355 views
1

我使用以下代碼作爲指南並修改了下面的代碼。 http://bendecplusplus.googlecode.com/svn/trunk/ssl_mycode/epoll_ssl/server.chttp://bendecplusplus.googlecode.com/svn/trunk/ssl_mycode/epoll_ssl/client.c基於epoll的非阻塞ssl_read()卡在循環中

我已經修改了服務器端的代碼如下:

do { 
count = SSL_read (ssl, buf, sizeof(buf)); // get request 
switch (SSL_get_error (ssl, count)) { 
    case SSL_ERROR_NONE: 
      buf[count] = 0; 
      printf("Client msg: \"%s\"\n", buf); 
      sprintf(reply, HTMLecho, buf); // construct reply 
      SSL_write(ssl, reply, strlen(reply)); // send reply 
      break; 
    case SSL_ERROR_WANT_READ: 
    case SSL_ERROR_WANT_WRITE: 
      continue; 
    case SSL_ERROR_ZERO_RETURN:   
      ERR_print_errors_fp(stderr); 
      printf("Performing exchange Error 2.\n"); 
      done = 1; 
      break; 
    default: 
      ERR_print_errors_fp(stderr); 
      printf("Performing exchange Error 3.\n"); 
      done = 1; 
      break; 
    } 
} while (ssl && count > 0); // SSL_pending(ssl) seems unreliable 

在客戶端我的代碼如下:

SSL_library_init(); 
ctx = InitCTX(); 
LoadCertificates(ctx, CertFile, KeyFile); 
server = OpenConnection(hostname, atoi(portnum)); 
ssl = SSL_new(ctx); /* create new SSL connection state */ 
SSL_set_fd(ssl, server); /* attach the socket descriptor */ 
    if (SSL_connect(ssl) == FAIL) /* perform the connection */ 
    { 
     ERR_print_errors_fp(stderr); 
    } else { 
    while(1){ 
     char *msg = "Hello??? are you there. lolololololololoooooooooooooooooooooooooooo"; 
     printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); 
     ShowCerts(ssl); /* get any certs */ 
     SSL_write(ssl, msg, strlen(msg)); /* encrypt & send message */ 
     bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */ 
     buf[bytes] = 0; 
     printf("Received: \"%s\"\n", buf); 
     sleep(1); 
     } 
     SSL_free(ssl); /* release connection state */ 
    } 
close(server); /* close socket */ 
SSL_CTX_free(ctx); /* release context */ 

我觀察被陷在環路在服務器端。任何指導表示讚賞。

+1

什麼瑪麗安說,加'buf [字節] = 0;''看起來像一個緩衝區溢出,如果SSL_read填充buf。 –

+0

確定,以便需要刪除或減1.「err = SSL_read(ssl,buf,sizeof(buf) - 1); \t if(err <= 0) \t { \t \t close(sd); \t \t \t \t SSL_CTX_free(ctx); ERR_print_errors_fp(stderr); \t \t return 1; \t} buf [err] ='\ 0';' – enthusiasticgeek

+0

@enthusiasticgeek - 請參閱[幫助中心](https://stackoverflow.com/about)和主題*通過編輯或評論*改進帖子。您試圖放置在評論中的代碼留下了很多不足之處...... – jww

回答

0

以下爲我工作的代碼。

   count = SSL_read(ssl, buf, sizeof(buf)); // get request 
       int32_t ssl_error = SSL_get_error (ssl, count); 
       switch (ssl_error) { 
       case SSL_ERROR_NONE: 
          printf("SSL_ERROR_NONE\n"); 
          break; 
       case SSL_ERROR_WANT_READ: 
          printf("SSL_ERROR_WANT_READ\n"); 
          break; 
       case SSL_ERROR_WANT_WRITE: 
          printf("SSL_ERROR_WANT_WRITE\n"); 
          break; 
       case SSL_ERROR_ZERO_RETURN: 
          printf("SSL_ERROR_ZERO_RETURN\n"); 
          break; 
       default: 
          break; 
       } 

       if ((count > 0) && (ssl_error == SSL_ERROR_NONE)) 
       { 
        buf[count] = 0; 
        printf("count > 0 Client msg: \"%s\"\n", buf); 
        sprintf(reply, HTMLecho, buf); // construct reply 
        SSL_write(ssl, reply, strlen(reply)); // send reply 
       } else if ((count < 0) && (ssl_error == SSL_ERROR_WANT_READ)){ 
        printf("count < 0 \n"); 
        if (errno != EAGAIN) 
        { 
         printf("count < 0 errno != EAGAIN \n"); 
         perror ("read"); 
         done = 1; 
        } 
        break; 
       } else if (count==0){ 
        ERR_print_errors_fp(stderr); 
        printf("count == 0 Client Disconnected.\n"); 
        done = 1; 
        break; 
       } 
2

你的循環很明顯。如果沒有什麼可讀的,SSL_read返回零並且錯誤代碼是SSL_ERROR_WANT_READ,那麼您執行continue可以返回到ssl_read

+0

請原諒我對SSL的瞭解,因爲我是新手。如果我必須根據事實終止這個循環,那麼現在沒有什麼可讀的,但是數據可能會在稍後時間到達,如何解決它。這是因爲客戶端代碼也有一個重複發送數據的循環。我不想從同一個客戶端再次執行ssl_accept。 – enthusiasticgeek