使用curl c++发送邮件



我试图使用curl c++发送电子邮件,我设法登录好,当我运行程序它工作正常,不抛出任何错误,但电子邮件从来没有来过。

这是我的代码:

#include <iostream>
#include <curl/curl.h>
static const char *payload_text =
"Date: Mon, 29 Nov 2010 21:54:29 +1100rn"
"To: " "mailto" "rn"
"From: " "mymail" "rn"
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>rn"
"Subject: SMTP example messagern"
"rn" /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.rn"
"rn"
"It could be a lot of lines, could be MIME encoded, whatever.rn"
"Check RFC5322.rn";
size_t read_function(char *buffer, size_t size, size_t nmemb,char *data)
{
size_t len;
if(size == 0 or nmemb == 0)
{
return 0;
}
if(data)
{
len = strlen(data);
memcpy(buffer, data, len);
return len;
}
return 0;  
}
int main()
{
CURL *curl;
CURLcode res = CURLE_OK;
const char *data = payload_text;

curl = curl_easy_init();
if(curl) 
{
curl_easy_setopt(curl, CURLOPT_USERNAME, "mymail"); 
curl_easy_setopt(curl, CURLOPT_PASSWORD, "password");
curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.gmail.com:587");
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, "my mail");
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, "mailto");
curl_easy_setopt(curl, CURLOPT_READDATA,payload_text);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_function);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
}
res = curl_easy_perform(curl);

if(res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %sn",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
return 0;
}

我认为问题在于curl选项READDATA和READUNCTION。在文档中说你必须把一个数据指针作为参数传递给READDATA。const char *data = payload_text;是数据指针,对吧?

然后READFUNCTION将返回数据大小的函数作为参数,我认为这就是size_t read_function(char *buffer, size_t size, size_t nmemb,char *data)正在做的。

我是新手,所以任何建议都会对我有好处。

我发现这是一个有用的起点:https://curl.se/libcurl/c/smtp-mail.html

你的代码有两个主要问题:
  1. 你的read_function没有跟踪多少有效载荷已被读取,所以它会不断地给libcurl相同的内容一遍又一遍,从来没有信号的消息结束。
  2. 您将CURLOPT_MAIL_RCPT设置为字符串,而实际上它应该是struct curl_slist *,因为可以有多个收件人。

这是一个固定的例子,我在我的电脑上测试,它工作。文件顶部的私有数据在发布前被修改。

#define USERNAME "david"
#define PASSWORD "xxxxx"
#define MAILTO "david@example.com"
#define MAILFROM "you@example.com"
#define SMTP "smtp://your.smtp.server.example.com:25"
#include <stdio.h>
#include <curl/curl.h>
const char * payload_text =
"Date: Mon, 29 Nov 2010 21:54:29 +1100rn"
"To: " MAILTO "rn"
"From: " MAILFROM "rn"
"Subject: SMTP example message with libcurl 6rn"
"rn"
"Hello world!rn";
struct ReadData
{
explicit ReadData(const char * str)
{
source = str;
size = strlen(str);
}
const char * source;
size_t size;
};
size_t read_function(char * buffer, size_t size, size_t nitems, ReadData * data)
{
size_t len = size * nitems;
if (len > data->size) { len = data->size; }
memcpy(buffer, data->source, len);
data->source += len;
data->size -= len;
return len;
}
int main()
{
CURL * curl = curl_easy_init();
if (!curl)
{
fprintf(stderr, "curl_easy_init failedn");
return 1;
}
curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME);
curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD);
curl_easy_setopt(curl, CURLOPT_URL, SMTP);
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM);
struct curl_slist * rcpt = NULL;
rcpt = curl_slist_append(rcpt, MAILTO);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt);
ReadData data(payload_text);
curl_easy_setopt(curl, CURLOPT_READDATA, &data);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_function);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
// If your server doesn't have a proper SSL certificate:
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %sn",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
return 0;
}

read_function:您正在更改不影响调用方字节缓冲区的本地指针buffer。您应该将数据复制到指向缓冲区

memcpy(buffer, data, len);

仅供参考,sizeof(char)保证为1,因此不需要。

另一个问题-函数永远不会返回0,表示所有数据都发送了,它一次又一次地发送相同的数据。您应该在第二次调用时返回0。或者将长度设置为选项CURLOPT_POSTFIELDSIZE_LARGE

参见示例smtp-mail.c

最新更新