2014-05-07 351 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