search

Home  >  Q&A  >  body text

C++ 用OpenSSL的BIO_xxx访问网页,BIO_read如何设置超时?

我程序是多线程的,为了方便访问http和https站,就用了OpenSSL的BIO_模块,以前没用过OpenSSL对这玩意不熟,程序访问某些网页后就一直没不断开,HTTP头已经把Connection字段设为“Close”,当接收完数据后我也会自己用代码断开。但有某些情况是连接上服务器后一直没有接到数据或接到一半卡住不动了,就想如遇这种情况设置BIO_read超时,但一直没成功。以前单纯用SOCKETS编程时,用select设置超时倒是挺方便的,这个怎么和它结合呢,望大伙儿不吝赐教!感激不尽!

测试连接是用select方式。

int CMySSL::Test_Connect(string szHost,int nPort,int nTimeout)
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0) return 0;

    struct sockaddr_in cliaddr;
    struct hostent *host;
    if(!(host = gethostbyname(szHost.c_str())))
    {
        printf("xxxx");
        return 0;
    }

    memset(&cliaddr,0,sizeof(struct sockaddr));
    cliaddr.sin_family = AF_INET;
    cliaddr.sin_port = htons(nPort);
    cliaddr.sin_addr = *((struct in_addr*)host->h_addr);

    int tt = nTimeout*1000;

    unsigned long ul = 1;
    int ret = ioctlsocket(sockfd,FIONBIO,(unsigned long*)&ul);
    if(ret == SOCKET_ERROR) return 0;

    connect(sockfd,(struct sockaddr*)&cliaddr,sizeof(cliaddr));

    TIMEVAL timeout;
    fd_set rs;
    FD_ZERO(&rs);
    FD_SET(sockfd,&rs);
    timeout.tv_sec = nTimeout;
    timeout.tv_usec = 0;
    ret = select(0,0,&rs,0,&timeout);
    if(ret <= 0)
    {
        closesocket(sockfd);
        return 0;
    }

    unsigned long ul1 = 0;
    ret = ioctlsocket(sockfd,FIONBIO,(unsigned long*)&ul1);
    if(ret==SOCKET_ERROR) return 0;
    ......
}
伊谢尔伦伊谢尔伦2803 days ago1155

reply all(2)I'll reply

  • 阿神

    阿神2017-04-17 11:52:42

    You first use BIO_get_fd to get the underlying fd, and then you can use select to do the timeout.

    reply
    0
  • 迷茫

    迷茫2017-04-17 11:52:42

    Should be set to non-blocking BIO, determine BIO_should_retry before further operations, the bottom layer of BIO has been encapsulated.

    reply
    0
  • Cancelreply