我在Linux上发送带有c ++的电子邮件。为此,我使用curl库,但是我对字符的表征有点奇怪。当我发送(作为主题或信息正文)“áéíóú”或“Móviláéíóú”时,电子邮件被正确查看“áéíóú”或“Móviláéíóú”。但是当我发送“Móvil”时,编码不正确被视为“Móvil”。
我已经更改了卷曲编码的标题,但它似乎根本不起作用。 我不知道该怎么办,所以感谢任何帮助。
可能我的错误接近
headers = curl_slist_append(headers, "Content-Type: text/html");
headers = curl_slist_append(headers, "charset: utf-8");
类代码如下:
.h
class SendEmail {
public:
SendEmail( std::string to,
std::string from,
std::string nameFrom,
std::string subject,
std::string body,
std::string cc );
virtual ~SendEmail();
CURLcode send(const std::string &url,
const std::string &userName,
const std::string &password);
private:
struct StringData {
std::string msg;
size_t bytesleft;
StringData(std::string &&m) : msg{ m }, bytesleft{ msg.size() } {}
StringData(std::string &m) = delete;
};
static std::string _dateTimeNow();
std::string _generateMessageId() const;
static size_t _payloadSource(void *ptr, size_t size, size_t nmemb, void *userp);
std::string _setPayloadText();
std::vector<std::string> split(std::string &text, char sep);
std::string _to, _from, _cc, _nameFrom, _subject, _body;};
.cpp
SendEmail::SendEmail( std::string to,
std::string from,
std::string nameFrom,
std::string subject,
std::string body,
std::string cc)
{
_to = to;
_from = from;
_nameFrom = nameFrom;
_subject = subject;
_body = body;
_cc = cc.empty() ? to : cc;
}
SendEmail::~SendEmail() {
}
CURLcode SendEmail::send(const std::string &url,
const std::string &userName,
const std::string &password)
{
std::vector<std::string> vectorTo;
std::vector<std::string> vectorCC;
CURLcode ret = CURLE_OK;
struct curl_slist *recipients = NULL;
CURL *curl = curl_easy_init();
StringData textData { _setPayloadText() };
if (curl) {
curl_easy_setopt(curl, CURLOPT_USERNAME, userName.c_str());
curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str());
curl_easy_setopt(curl, CURLOPT_URL, url .c_str());
// curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
//curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, ("<" + _from + ">").c_str());
vectorTo = split(_to, ';');
vectorCC = split(_cc, ';');
struct curl_slist *headers=NULL;
headers = curl_slist_append(headers, "Content-Type: text/html");
headers = curl_slist_append(headers, "charset: utf-8");
headers = curl_slist_append(headers, "charsets: utf-8");
/* pass our list of custom made headers */
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
for(string to : vectorTo){
if(to.empty()==false){
recipients = curl_slist_append(recipients, ("<" + to + ">").c_str());
}
}
for(string cc : vectorCC){
if(cc.empty()==false){
recipients = curl_slist_append(recipients, ("<" + cc + ">").c_str());
}
}
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, _payloadSource);
curl_easy_setopt(curl, CURLOPT_READDATA, &textData);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
ret = curl_easy_perform(curl);
if (ret != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(ret) << "\n";
}
curl_slist_free_all(recipients);
curl_slist_free_all(headers); /* free the header list */
curl_easy_cleanup(curl);
}
vectorTo.clear();
vectorCC.clear();
return ret;
}
std::string SendEmail::_dateTimeNow()
{
const int RFC5322_TIME_LEN = 32;
std::string ret;
ret.resize(RFC5322_TIME_LEN);
time_t tt;
#ifdef _MSC_VER
time(&tt);
tm *t = localtime(&tt);
#else
tm tv, *t = &tv;
tt = time(&tt);
localtime_r(&tt, t);
#endif
strftime(&ret[0], RFC5322_TIME_LEN, "%a, %d %b %Y %H:%M:%S %z", t);
return ret;
}
std::string SendEmail::_generateMessageId() const
{
const int MESSAGE_ID_LEN = 37;
tm t;
time_t tt;
time(&tt);
std::string ret;
ret.resize(15);
#ifdef _MSC_VER
gmtime_s(&t, &tt);
#else
gmtime_r(&tt, &t);
#endif
strftime(const_cast<char *>(ret.c_str()),
MESSAGE_ID_LEN,
"%Y%m%d%H%M%S.",
&t);
ret.reserve(MESSAGE_ID_LEN);
static const char alphaNum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
while (ret.size() < MESSAGE_ID_LEN) {
ret += alphaNum[rand() % (sizeof(alphaNum) - 1)];
}
return ret;
}
size_t SendEmail::_payloadSource(void *ptr, size_t size, size_t nmemb, void *userp)
{
StringData *text = reinterpret_cast<StringData *>(userp);
if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1) || (text->bytesleft == 0)) {
return 0;
}
if ((nmemb * size) >= text->msg.size()) {
text->bytesleft = 0;
return text->msg.copy(reinterpret_cast<char *>(ptr), text->msg.size());
}
return 0;
}
std::string SendEmail::_setPayloadText()
{
std::string ret;
ret += "Date: " + _dateTimeNow() + ">\r\n";
ret += "To: <" + _to + ">\r\n";
ret += "From: <" + _from + "> (" + _nameFrom + ")\r\n";
ret += "Cc: <" + _cc + "> (" + _nameFrom + ")\r\n";
ret += "Message-ID: <" + _generateMessageId() + "@" + _from.substr(_from.find('@') + 1) + ">\r\n";
ret += "Subject: " + _subject + "\r\n";
ret += "\r\n";
ret += _body + "\r\n";
ret += "\r\n";
ret += "\r\n"; // "It could be a lot of lines, could be MIME encoded, whatever.\r\n";
ret += "\r\n"; // "Check RFC5322.\r\n";
return ret;
}
std::vector<std::string> SendEmail::split(std::string &text, char sep) {
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
答案 0 :(得分:0)
我终于解决了这个问题。这是电子邮件标题的编码。只需要修改以下功能:
std::string SendEmail::_setPayloadText()
{
std::string ret;
ret += "Content-Type: text/plain; charset=utf-8; \r\n";
ret += "Date: " + _dateTimeNow() + ">\r\n";
ret += "To: <" + _to + ">\r\n";
ret += "From: <" + _from + "> (" + _nameFrom + ")\r\n";
ret += "Cc: <" + _cc + "> (" + _nameFrom + ")\r\n";
ret += "Message-ID: <" + _generateMessageId() + "@" + _from.substr(_from.find('@') + 1) + ">\r\n";
ret += "Subject: " + _subject + "\r\n";
ret += "\r\n";
ret += _body + "\r\n";
ret += "\r\n";
ret += "\r\n"; // "It could be a lot of lines, could be MIME encoded, whatever.\r\n";
ret += "\r\n"; // "Check RFC5322.\r\n";
cout<<ret<<endl;
return ret;
}
添加以下行:
"Content-Type: text/plain; charset=utf-8; \r\n";