使用libCurl从gmail POP3帐户中读取电子邮件

时间:2013-11-06 12:28:08

标签: c++ libcurl pop3

我目前正在开发一个C ++项目,该项目必须能够从gmail POP3帐户中读取电子邮件,就像标题所说的那样。同样重要的是,我需要下载邮件及其正文的附件(是编码base64?)。 事实是每个人都建议使用libCurl来完成这项任务,但是他们网站上的代码示例不起作用。 我在Libcurl website上看到了这个例子:

#include <stdio.h>
#include <curl/curl.h>

int main(void)
{
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    if(curl)
    {
         /* Set username and password */ 
         curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");

         /* This will only fetch the message with ID "1" of the given mailbox */ 
         curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user@pop.example.com/1");

         /* Perform the request, res will get the return code */ 
         res = curl_easy_perform(curl);

         /* Check for errors */ 
         if(res != CURLE_OK)
         fprintf(stderr, "curl_easy_perform() failed: %s\n",
                curl_easy_strerror(res));

         /* always cleanup */ 
         curl_easy_cleanup(curl);
    }
    return 0;
}

如您所见,代码看起来非常容易通过收件箱内的电子邮件获取电子邮件,但是当我尝试使用 CURLcode curl_easy_perform(CURL *)执行操作时,该函数不会返回任何内容并且过程'死'所以我不能跳过这一行。 我的代码是以下代码:

void MailServer::Open(char *username,char *password)
{
    m_username = username; //username = example@gmail.com
    m_password = password; //password = blabla123

    curl = curl_easy_init();
    curl_easy_setopt(curl,CURLOPT_USERNAME,username);
    curl_easy_setopt(curl,CURLOPT_PASSWORD,password);

    m_popsAccount = "pop3s://" + m_username +"/1";      

    curl_easy_setopt(curl, CURLOPT_URL, m_popsAccount.c_str());
    res = curl_easy_perform(curl); //here does not return anything

}

我试图在网上找到一些“清晰”的例子,但我真的不能...... 有人可以帮我一把吗? :)

1 个答案:

答案 0 :(得分:11)

我做到了!这里有一个很好的示例,说明如何访问gmail帐户并查看其中的内容。我目前正在解析内部信息,因为实际上它只检索收件箱中的邮件数量及其大小。 如果您将网址更改为“pops://pop.gmail.com:995/1”,它将返回信息的内容,并包含附件的base64编码。谢谢无论如何......这是代码! :)

#pragma region Types
struct MemoryStruct {
    char *memory;
    size_t size;
};  
#pragma endregion

void MailServer::Open(char *username,char *password)
{
    m_username = username;
    m_password = password;
    struct MemoryStruct chunk;

    chunk.memory = (char*) malloc(1);  //crecerá según sea necesario con el realloc
    chunk.size = 0;    //no hay datos en este punto

    //inicializacion
    curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();


    //login
    curl_easy_setopt(curl,CURLOPT_USERNAME,username);
    curl_easy_setopt(curl,CURLOPT_PASSWORD,password);

    m_popsAccount = "pop3s://pop.gmail.com:995/";       

    curl_easy_setopt(curl, CURLOPT_URL, m_popsAccount.c_str());
    curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); 
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); 
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); 

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); 

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

    //some servers needs this validation
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

    res = curl_easy_perform(curl); 

    if(res != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform() failed: %s\n",
        curl_easy_strerror(res));
    }
    else 
    {
        /*
        here is where you can work with the data inside the chunk...
        */  
        printf("%s\n",chunk.memory); //here is the information
        printf("%lu bytes retrieved\n", (long)chunk.size);  
  }

    //se libera la memoria si hay datos
    if(chunk.memory)
        free(chunk.memory);
    /* always cleanup */ 

    curl_global_cleanup();
}


size_t MailServer::WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
    size_t realsize = size * nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct *)userp;

    mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
    if(mem->memory == NULL) {
        /* out of memory! */ 
        printf("not enough memory (realloc returned NULL)\n");
        return 0;
    }

    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;

    return realsize;
}