使用libcurl

问题描述

我维护了一个用VC 2017编写的IMAP应用程序(Windows),该应用程序使用Winsock2作为基础连接。我正在研究使用libcurl而不是Winsock来减轻代理和SSL / TLS等各种问题的负担。

我知道libcurl中的高级IMAP函数,但是我不想去那儿,我需要对IMAP进行更直接的控制,并且需要重用现有代码。所以我想尝试一下curl_easy_send()和curl_easy_recv()。

到目前为止运气不佳。我基本上是在运行libcurl附带的演示程序sendrecv.c(如下所示,是我的稍加修改的版本)。

当您连接到IMAP服务器时,它会立即发回响应,列出其功能。客户端不需要请求它。在我的程序中,我可以连接到我的测试服务器(outlook.office365.com),如果我使用端口143(不安全的IMAP端口),则可以收到响应。但是,如果我使用安全端口993,则该程序将挂在select()命令上,并在60秒后超时。

所以大概我对SSL有问题。我尝试使用CURLOPT_USE_SSL启用SSL,但这没什么区别。我在这里想念什么?

P.S。可能是无关的问题,但是当我尝试连接到imap.gmail.com时,连接失败,并显示错误56(CURLE_RECV_ERROR)。

static int wait_on_socket(curl_socket_t sockfd,int for_recv,long timeout_ms)
{
    struct timeval tv;
    fd_set infd,outfd,errfd;
    int res;

    tv.tv_sec = timeout_ms / 1000;
    tv.tv_usec = (timeout_ms % 1000) * 1000;

    FD_ZERO(&infd);
    FD_ZERO(&outfd);
    FD_ZERO(&errfd);

    FD_SET(sockfd,&errfd); /* always check for error */

    if (for_recv) {
        FD_SET(sockfd,&infd);
    }
    else {
        FD_SET(sockfd,&outfd);
    }

    /* select() returns the number of signalled sockets or -1 */
    printf("starting select\n");
    res = select((int)sockfd + 1,&infd,&outfd,&errfd,&tv);
    printf("finished select,res=%d\n",res);
    return res;
}


int main()
{
    CURL *curl;
    CURLcode res;
    int port = 993;
    curl_socket_t sockfd;
    char imap_host[256] = "";
    char buf[1024];
    size_t nread;

    printf("Starting sendrecv demo\n");

    curl = curl_easy_init();
    if (!curl) {
        printf("Unable to initialize curl\n");
        return(0);
    }

    curl_easy_setopt(curl,CURLOPT_DEBUGFUNCTION,debug_function);
    curl_easy_setopt(curl,CURLOPT_VERBOSE,true);

    //strcpy_s(imap_host,"imap.gmail.com");
    strcpy_s(imap_host,"outlook.office365.com");
    curl_easy_setopt(curl,CURLOPT_URL,imap_host);
    curl_easy_setopt(curl,CURLOPT_CONNECT_ONLY,1L);
    curl_easy_setopt(curl,CURLOPT_PORT,port);
    curl_easy_setopt(curl,CURLOPT_USE_SSL,CURLUSESSL_TRY);
    res = curl_easy_perform(curl);

    printf("Return from connect: %d\n",res);

    /* Extract the socket from the curl handle - we'll need it for waiting. */
    res = curl_easy_getinfo(curl,CURLINFO_ACTIVESOCKET,&sockfd);
    if (res != CURLE_OK) {
        printf("Error getting socket\n");
        return(0);
    }

    printf("Reading IMAP response\n");

    while (1) {
        /* Warning: This example program may loop indefinitely (see above). */
        
        do {
            nread = 0;
            res = curl_easy_recv(curl,buf,sizeof(buf),&nread);

            if (res == CURLE_AGAIN && !wait_on_socket(sockfd,1,60000L)) {
                printf("Error: timeout.\n");
                return(0);
            }
        } while (res == CURLE_AGAIN);

        if (res != CURLE_OK) {
            printf("Error: %s\n",curl_easy_strerror(res));
            break;
        }

        if (nread == 0) {
            /* end of the response */
            break;
        }

        printf("Received %d bytes\n",nread);
        buf[nread] = 0;
        break;

    }

    printf("response: %s\n",buf);

    /* always cleanup */
    curl_easy_cleanup(curl);

    return(0);


}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)