2013-08-08 4 views
2

select 함수를 사용하여 클라이언트에서 server.l에 연결하는 비 차단 연결을 사용하려고합니다. 일부 코드가있는 자습서를 찾고 이에 적응하려고했습니다.select on 리눅스 플랫폼에서 SSL_connect를 설정하는 방법

... 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
err = connect(sockfd,(struct sockaddr*)&sa,sizeof(sa)); 
... 
SSL_set_fd(pssl,sockfd); 
err = SSL_connect_nonb(pssl,sockfd,60); 
if(err <=0){ 
    printf("SSL_connect:%s\n",ERR_error_string(SSL_get_error(pssl,err),NULL)); 
    return -1; 
} 
... 

SSL_connect_nonb 기능 노호 같이 정의된다

int SSL_connect_nonb(SSL*pssl,int sockfd, int nsec) 
{ 
    int flags, error; 
    socklen_t len; 
    fd_set rset, wset; 
    struct timeval tval; 
    flags = fcntl(sockfd, F_GETFL, 0); 
    fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); 
    int err = SSL_connect(pssl); 
    int err2 = SSL_get_error(pssl,err); 
    switch(err2) { 
      default: 
       printf("SSL_connect err=%s\n",ERR_error_string(err2,0)); 
       return -1; 
       break; 
      case SSL_ERROR_WANT_READ: 
      case SSL_ERROR_WANT_WRITE: 
       break; 
    } 
    FD_ZERO(&rset); 
    FD_ZERO(&wset); 
    FD_SET(sockfd, &rset); 
    FD_SET(sockfd, &wset); 
    tval.tv_sec = nsec; 
    tval.tv_usec = 0; 
    if (select(sockfd+1, &rset, &wset, NULL,nsec ? &tval:NULL) == 0) { 
     return -1; 
    } 
    if(FD_ISSET(sockfd,&rset) || FD_ISSET(sockfd, &wset)) { 
     len = sizeof(error); 
     if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0){ 
      return -1; 
     } 
    }else{ 
     printf("sockfd not set\n"); 
     return -1; 
    } 
    fcntl(sockfd, F_SETFL, flags); 
    if (error) { 
     return -1; 
    } 
    return 1; 
} 

sockfd와 연결로 정확, 문제가 있음을 상기 선택 함수 반환을 aValue = 1 (실제 조건 FD_ISSET (sockfd와 SSL_connect_nonb에서, & wset) 성공 모든 시간),하지만이 같은 차단 방법을 사용하는 경우 :

....  
SSL_set_fd(pssl,sockfd); 
err = SSL_connect(pssl); 
if(err <=0){ 
    printf("SSL_connect:%s\n",ERR_error_string(SSL_get_error(pssl,err),NULL)); 
    return -1; 
} 
... 

SSL_connect이 성공하지, 그래서 어떻게 선택 함수를 호출하여 비 블로킹 소켓에 SSL_connect 함께 할 수 있기 때문에 ERR의 값이 0?

답변

4

SSL_connect(), 일명 SSL 클라이언트 핸드 셰이크는 복잡한 프로세스이므로 서버를 여러 번 왕복해야합니다. 따라서 비 블로킹 소켓에 SSL_connect()을 실행하면 한 번만 실행하면됩니다. SSL_ERROR_WANT_READ 또는 SSL_ERROR_WANT_WRITE이 나오면 다른 오류로 인해 성공하거나 실패 할 때까지 SSL_connect()을 다시 시도해야합니다.

관련 문제