结合MIME C++ library与CURL发送带附件的邮件
2013-03-15 15:28
381 查看
使用CURL发送不带附件的例子,在CURL的官方范例simplesmtp.cpp和smtp_tls.cpp中,认真看看,使用不难。而发送附件的例子则没有了,需要了解MIME协议,将邮件按照MIME编码,在CURLOPT_READFUNCTION发送出去即可。直接用字符串拼凑MIME有点麻烦,可以结合MIME C++ library完成这项工作。MIME C++ library的下载地址http://www.codesink.org/mimetic_mime_library.html。
显示如下:
From: me <me@domain.com> //From:简称<邮箱地址>
To: you <you@domain.com> //To:简称<邮箱地址>
Subject: my first mimetic msg //邮件标题
hello there! //正文内容
这是一个最简单的MIME 流了。如果是带附件的 那么:
Content-Type: multipart/mixed;
boundary="----lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_"
From: me@sina.com.cn
To: you@sina.com.cn
CC: <he@sina.com.cn>;<she@sina.com.cn>;
Subject: my first mimetic msg
Mime-Version: 1.0
------lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_
Content-Type: application/octet-stream; name="readme.txt"
Content-Disposition : attachment; filename=readme.txt
Content-Transfer-Encoding: base64
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09DQogICAgQ09OU09MRSBBUFBMSUNBVElPTiA6IHRlc3RfbWltZXRpYyBQ
cm9qZWN0IE92ZXJ2aWV3DQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCg0KQXBwV2l6YXJkIGhhcyBjcmVhdGVk
IHRoaXMgdGVzdF9taW1ldGljIGFwcGxpY2F0aW9uIGZvciB5b3UuDQoNClRoaXMgZmlsZSBjb250
YWlucyBhIHN1bW1hcnkgb2Ygd2hhdCB5b3Ugd2lsbCBmaW5kIGluIGVhY2ggb2YgdGhlIGZpbGVz
IHRoYXQNCm1ha2UgdXAgeW91ciB0ZXN0X21pbWV0aWMgYXBwbGljYXRpb24uDQoNCg0KdGVzdF9t
aW1ldGljLnZjeHByb2oNCiAgICBUaGlzIGlzIHRoZSBtYWluIHByb2plY3QgZmlsZSBmb3IgVkMr
KyBwcm9qZWN0cyBnZW5lcmF0ZWQgdXNpbmcgYW4gQXBwbGljYXRpb24gV2l6YXJkLg0KICAgIEl0
IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSB2ZXJzaW9uIG9mIFZpc3VhbCBDKysgdGhh
dCBnZW5lcmF0ZWQgdGhlIGZpbGUsIGFuZA0KICAgIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwbGF0
Zm9ybXMsIGNvbmZpZ3VyYXRpb25zLCBhbmQgcHJvamVjdCBmZWF0dXJlcyBzZWxlY3RlZCB3aXRo
IHRoZQ0KICAgIEFwcGxpY2F0aW9uIFdpemFyZC4NCg0KdGVzdF9taW1ldGljLnZjeHByb2ouZmls
dGVycw0KICAgIFRoaXMgaXMgdGhlIGZpbHRlcnMgZmlsZSBmb3IgVkMrKyBwcm9qZWN0cyBnZW5l
cmF0ZWQgdXNpbmcgYW4gQXBwbGljYXRpb24gV2l6YXJkLiANCiAgICBJdCBjb250YWlucyBpbmZv
cm1hdGlvbiBhYm91dCB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiB0aGUgZmlsZXMgaW4geW91ciBw
cm9qZWN0IA0KICAgIGFuZCB0aGUgZmlsdGVycy4gVGhpcyBhc3NvY2lhdGlvbiBpcyB1c2VkIGlu
IHRoZSBJREUgdG8gc2hvdyBncm91cGluZyBvZiBmaWxlcyB3aXRoDQogICAgc2ltaWxhciBleHRl
bnNpb25zIHVuZGVyIGEgc3BlY2lmaWMgbm9kZSAoZm9yIGUuZy4gIi5jcHAiIGZpbGVzIGFyZSBh
c3NvY2lhdGVkIHdpdGggdGhlDQogICAgIlNvdXJjZSBGaWxlcyIgZmlsdGVyKS4NCg0KdGVzdF9t
aW1ldGljLmNwcA0KICAgIFRoaXMgaXMgdGhlIG1haW4gYXBwbGljYXRpb24gc291cmNlIGZpbGUu
DQoNCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQpPdGhlciBzdGFuZGFyZCBmaWxlczoNCg0KU3RkQWZ4
LmgsIFN0ZEFmeC5jcHANCiAgICBUaGVzZSBmaWxlcyBhcmUgdXNlZCB0byBidWlsZCBhIHByZWNv
bXBpbGVkIGhlYWRlciAoUENIKSBmaWxlDQogICAgbmFtZWQgdGVzdF9taW1ldGljLnBjaCBhbmQg
YSBwcmVjb21waWxlZCB0eXBlcyBmaWxlIG5hbWVkIFN0ZEFmeC5vYmouDQoNCi8vLy8vLy8vLy8v
Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
Ly8vLy8vLy8vDQpPdGhlciBub3RlczoNCg0KQXBwV2l6YXJkIHVzZXMgIlRPRE86IiBjb21tZW50
cyB0byBpbmRpY2F0ZSBwYXJ0cyBvZiB0aGUgc291cmNlIGNvZGUgeW91DQpzaG91bGQgYWRkIHRv
IG9yIGN1c3RvbWl6ZS4NCg0KLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCg==
------lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_--
在这里值得一说的是Content-Type: multipart/mixed;
boundary="----lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_"这里说明了邮件有多块,以----lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_为分割标识符。如果想给邮件中添加新的一个块,比如说,除了附件还需要个正文那么需要再new mimetic::MimeEntity* pMe
#include "stdafx.h" #include <string> #include <iostream> #include <mimetic/mimetic.h> #include <sstream> #include <iterator> #include <stdio.h> #include <fstream> int _tmain(int argc, _TCHAR* argv[]) { mimetic::MimeEntity me; me.header().from("me <me@domain.com>"); me.header().to("you <you@domain.com>"); me.header().subject("my first mimetic msg"); me.body().assign("hello there!"); std::cout << me <<std::endl; return 0; }
显示如下:
From: me <me@domain.com> //From:简称<邮箱地址>
To: you <you@domain.com> //To:简称<邮箱地址>
Subject: my first mimetic msg //邮件标题
hello there! //正文内容
这是一个最简单的MIME 流了。如果是带附件的 那么:
#include "stdafx.h" #include <string> #include <iostream> #include <mimetic/mimetic.h> #include <sstream> #include <iterator> #include <stdio.h> #include <fstream> int _tmain(int argc, _TCHAR* argv[]) { mimetic::MultipartMixed head; //写件人 head.header().from("<me@sina.com.cn>"); //收件人 head.header().to("<you@sina.com.cn>"); //抄送 head.header().cc("<he@sina.com.cn>;<she@sina.com.cn>;"); //标题 head.header().subject("my first mimetic msg"); //MIME协议版本 head.header().push_back(mimetic::Field("Mime-Version","1.0")); //正文,由于是MultipartMixed,这个内容是会被忽略的 head.body().assign("hello there!"); //创建一个新的块,在这里是附件 mimetic::MimeEntity* pMe = new mimetic::MimeEntity; //下面的代码就是开始设置这一段邮件内容的头了 //记住这里千万不能写成 //pMe->header().push_back(mimetic::Field("Content-Type","pplication/octet-stream")); //pMe->header().push_back(mimetic::Field("name","readme.txt")); pMe->header().push_back(mimetic::Field("Content-Type: application/octet-stream; name=readme.txt")); //这里和上一句需要注意的地方一样,这里说明了这个块是一个附件 pMe->header().push_back(mimetic::Field("Content-Disposition : attachment; filename=readme.txt")); //说明这个块是以BASE64编码的 pMe->header().push_back(mimetic::Field("Content-Transfer-Encoding","base64")); //设置完头以后,加载具体内容 FILE *pfile = fopen(".\\readme.txt","rb"); char buffer[4096]; uint32_t totalreadbytes = 0; while (!feof(pfile)) { //读文件 uint32_t readbytes = fread(buffer, 1, 4028, pfile); if (ferror(pfile) || readbytes == 0) { break; } totalreadbytes += readbytes; mimetic::Base64::Encoder b64; std::stringstream temp; std::ostreambuf_iterator<char> out(temp); //转为BASE64编码,目标存放至std::stringstream中 mimetic::code(buffer, buffer + readbytes, b64, out); std::string str = temp.str(); std::cout<<str; //将转换后的内容放入块中,不要贪方便写成 //pMe->load(temp.str().begin(), temp.str().end(), mimetic::imNone); //会崩溃的 pMe->load(str.begin(), str.end(), mimetic::imNone); } std::cout<<head; return 0; }显示的MIME流如下:
Content-Type: multipart/mixed;
boundary="----lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_"
From: me@sina.com.cn
To: you@sina.com.cn
CC: <he@sina.com.cn>;<she@sina.com.cn>;
Subject: my first mimetic msg
Mime-Version: 1.0
------lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_
Content-Type: application/octet-stream; name="readme.txt"
Content-Disposition : attachment; filename=readme.txt
Content-Transfer-Encoding: base64
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09DQogICAgQ09OU09MRSBBUFBMSUNBVElPTiA6IHRlc3RfbWltZXRpYyBQ
cm9qZWN0IE92ZXJ2aWV3DQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCg0KQXBwV2l6YXJkIGhhcyBjcmVhdGVk
IHRoaXMgdGVzdF9taW1ldGljIGFwcGxpY2F0aW9uIGZvciB5b3UuDQoNClRoaXMgZmlsZSBjb250
YWlucyBhIHN1bW1hcnkgb2Ygd2hhdCB5b3Ugd2lsbCBmaW5kIGluIGVhY2ggb2YgdGhlIGZpbGVz
IHRoYXQNCm1ha2UgdXAgeW91ciB0ZXN0X21pbWV0aWMgYXBwbGljYXRpb24uDQoNCg0KdGVzdF9t
aW1ldGljLnZjeHByb2oNCiAgICBUaGlzIGlzIHRoZSBtYWluIHByb2plY3QgZmlsZSBmb3IgVkMr
KyBwcm9qZWN0cyBnZW5lcmF0ZWQgdXNpbmcgYW4gQXBwbGljYXRpb24gV2l6YXJkLg0KICAgIEl0
IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSB2ZXJzaW9uIG9mIFZpc3VhbCBDKysgdGhh
dCBnZW5lcmF0ZWQgdGhlIGZpbGUsIGFuZA0KICAgIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwbGF0
Zm9ybXMsIGNvbmZpZ3VyYXRpb25zLCBhbmQgcHJvamVjdCBmZWF0dXJlcyBzZWxlY3RlZCB3aXRo
IHRoZQ0KICAgIEFwcGxpY2F0aW9uIFdpemFyZC4NCg0KdGVzdF9taW1ldGljLnZjeHByb2ouZmls
dGVycw0KICAgIFRoaXMgaXMgdGhlIGZpbHRlcnMgZmlsZSBmb3IgVkMrKyBwcm9qZWN0cyBnZW5l
cmF0ZWQgdXNpbmcgYW4gQXBwbGljYXRpb24gV2l6YXJkLiANCiAgICBJdCBjb250YWlucyBpbmZv
cm1hdGlvbiBhYm91dCB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiB0aGUgZmlsZXMgaW4geW91ciBw
cm9qZWN0IA0KICAgIGFuZCB0aGUgZmlsdGVycy4gVGhpcyBhc3NvY2lhdGlvbiBpcyB1c2VkIGlu
IHRoZSBJREUgdG8gc2hvdyBncm91cGluZyBvZiBmaWxlcyB3aXRoDQogICAgc2ltaWxhciBleHRl
bnNpb25zIHVuZGVyIGEgc3BlY2lmaWMgbm9kZSAoZm9yIGUuZy4gIi5jcHAiIGZpbGVzIGFyZSBh
c3NvY2lhdGVkIHdpdGggdGhlDQogICAgIlNvdXJjZSBGaWxlcyIgZmlsdGVyKS4NCg0KdGVzdF9t
aW1ldGljLmNwcA0KICAgIFRoaXMgaXMgdGhlIG1haW4gYXBwbGljYXRpb24gc291cmNlIGZpbGUu
DQoNCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQpPdGhlciBzdGFuZGFyZCBmaWxlczoNCg0KU3RkQWZ4
LmgsIFN0ZEFmeC5jcHANCiAgICBUaGVzZSBmaWxlcyBhcmUgdXNlZCB0byBidWlsZCBhIHByZWNv
bXBpbGVkIGhlYWRlciAoUENIKSBmaWxlDQogICAgbmFtZWQgdGVzdF9taW1ldGljLnBjaCBhbmQg
YSBwcmVjb21waWxlZCB0eXBlcyBmaWxlIG5hbWVkIFN0ZEFmeC5vYmouDQoNCi8vLy8vLy8vLy8v
Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
Ly8vLy8vLy8vDQpPdGhlciBub3RlczoNCg0KQXBwV2l6YXJkIHVzZXMgIlRPRE86IiBjb21tZW50
cyB0byBpbmRpY2F0ZSBwYXJ0cyBvZiB0aGUgc291cmNlIGNvZGUgeW91DQpzaG91bGQgYWRkIHRv
IG9yIGN1c3RvbWl6ZS4NCg0KLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCg==
------lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_--
在这里值得一说的是Content-Type: multipart/mixed;
boundary="----lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_"这里说明了邮件有多块,以----lrsJRnnv8qrhVhSN0z5KGo2eQwzHwv_LA_MGCzpaJN87zTe1=_2_为分割标识符。如果想给邮件中添加新的一个块,比如说,除了附件还需要个正文那么需要再new mimetic::MimeEntity* pMe
//添加一段正文 mimetic::MimeEntity* pMe2 = new mimetic::MimeEntity; //说明块是一段文字,文字使用GB2312字符集 pMe2->header().push_back(mimetic::Field("Content-Type: text/plain; charset=GB2312")); pMe2->header().push_back(mimetic::Field("Content-Transfer-Encoding","base64")); //把这一块加入到整个邮件中 head.body().parts().push_back(pMe2);到此为止所需要的流已经生成了,剩下的就是在CURL中发送出去。
// smtp_ex01.cpp : Defines the entry point for the console application. // #include "stdafx.h" /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ***************************************************************************/ #include <stdio.h> #include <mimetic/mimetic.h> #include <curl/curl.h> #include <string.h> #include <iostream> #include <sstream> #include <stdio.h> /* This is a simple example showing how to send mail using libcurl's SMTP * capabilities. It builds on the simplesmtp.c example, adding some * authentication and transport security. */ #define FROM "<me@test.com.cn>" #define TO "<you@test.com.cn>" #define CC "<he@test.com.cn>" #define BUFFERR_SIZE 4096 struct UserData { std::stringstream ss; size_t total; UserData() :total(0) { } }; static size_t my_read(void *ptr, size_t size, size_t nmemb, void *userp) { struct UserData * pstream = static_cast<struct UserData *>(userp); //assert(pstream); if (pstream->ss.eof()) { //也是因为移动到末尾时tellg()返回的数据总是不对 return 0; } size_t before = pstream->ss.tellg(); pstream->ss.read((char*)ptr, size*nmemb); size_t after = pstream->ss.tellg(); if (pstream->ss.eof()) { //对std::stringstream不熟悉,不知道为什么移动到末尾后 //tellg()返回的数据总是不对 std::cout<<(pstream->total - before)<<std::endl; return pstream->total - before; } std::cout<<(after - before)<<std::endl; return after - before; } int main(void) { CURL *curl; CURLcode res; struct curl_slist *recipients = NULL; mimetic::MultipartMixed head; head.header().from("<me@test.com.cn>"); head.header().to("<you@test.com.cn>"); head.header().cc("<he@test.com.cn>"); head.header().subject("my first mimetic msg"); head.header().push_back(mimetic::Field("Mime-Version","1.0")); head.header().push_back(mimetic::Field("Message-ID","<dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>")); head.body().assign("hello there!"); mimetic::MimeEntity* pMe = new mimetic::MimeEntity; pMe->header().push_back(mimetic::Field("Content-Type: application/octet-stream; name=readme.txt")); pMe->header().push_back(mimetic::Field("Content-Disposition : attachment; filename=readme.txt")); pMe->header().push_back(mimetic::Field("Content-Transfer-Encoding","base64")); FILE *pfile = fopen(".\\readme.txt","rb"); char buffer[BUFFERR_SIZE]; uint32_t totalreadbytes = 0; while (!feof(pfile)) { uint32_t readbytes = fread(buffer, 1, BUFFERR_SIZE - 1, pfile); if (ferror(pfile) || readbytes == 0) { break; } totalreadbytes += readbytes; mimetic::Base64::Encoder b64; std::stringstream temp; std::ostreambuf_iterator<char> out(temp); buffer[readbytes] = '\0'; mimetic::code(buffer, buffer + readbytes, b64, out); std::string str = temp.str(); pMe->load(str.begin(), str.end(), mimetic::imNone); } head.body().parts().push_back(pMe); struct UserData ud; ud.ss<<head; ud.ss.seekg(0, std::ios::end); ud.total = ud.ss.tellg(); ud.ss.seekg(0, std::ios::beg); curl = curl_easy_init(); if (curl) { /* This is the URL for your mailserver. Note the use of port 587 here, * instead of the normal SMTP port (25). Port 587 is commonly used for * secure mail submission (see RFC4403), but you should use whatever * matches your server configuration. */ curl_easy_setopt(curl, CURLOPT_URL, "smtp://mainserver.example.net:25");//"smtp://mainserver.example.net:25"); /* In this example, we'll start with a plain text connection, and upgrade * to Transport Layer Security (TLS) using the STARTTLS command. Be careful * of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer * will continue anyway - see the security discussion in the libcurl * tutorial for more details. */ //curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); /* If your server doesn't have a valid certificate, then you can disable * part of the Transport Layer Security protection by setting the * CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false). * curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); * curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); * That is, in general, a bad idea. It is still better than sending your * authentication details in plain text though. * Instead, you should get the issuer certificate (or the host certificate * if the certificate is self-signed) and add it to the set of certificates * that are known to libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See * docs/SSLCERTS for more information. */ //curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem"); /* A common reason for requiring transport security is to protect * authentication details (user names and passwords) from being "snooped" * on the network. Here is how the user name and password are provided: */ curl_easy_setopt(curl, CURLOPT_USERNAME, "test@test.com"); curl_easy_setopt(curl, CURLOPT_PASSWORD, "*****"); /* value for envelope reverse-path */ curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM); /* Add two recipients, in this particular case they correspond to the * To: and Cc: addressees in the header, but they could be any kind of * recipient. */ recipients = curl_slist_append(recipients, TO); recipients = curl_slist_append(recipients, CC); curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients); /* In this case, we're using a callback function to specify the data. You * could just use the CURLOPT_READDATA option to specify a FILE pointer to * read from. */ curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read); curl_easy_setopt(curl, CURLOPT_READDATA, &ud); // curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source); // curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx); /* Since the traffic will be encrypted, it is very useful to turn on debug * information within libcurl to see what is happening during the transfer. */ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); /* send the message (including headers) */ res = curl_easy_perform(curl); /* free the list of recipients and clean up */ curl_slist_free_all(recipients); curl_easy_cleanup(curl); } return 0; }需要注意的是MIME C++ library构造邮件流的时候是将所有内容加载至内存中的,对于大的附件还得自己拼凑MIME流,不过通过对MIME C++ library学习了MIME协议这应该不是太难的问题了。
相关文章推荐
- 结合MIME C++ library与CURL发送带附件的邮件
- 邮件发送后附件名称或下载附件名称是乱码的解决(C++)
- C++发送邮件和附件
- 邮件正文及其附件的发送的C++实现
- 邮件正文及其附件的发送的C++实现
- perl模块之MIME::Lite发送有附件的邮件
- spring的jJavaMailImp和MimeMessageHelper结合发送邮件
- mail结合uuencode快速发送邮件附件 推荐
- C++发送邮件和附件(转)
- perl模块之MIME::Lite发送有附件的邮件
- 邮件正文及其附件的发送的C++实现
- C++实现含附件的邮件发送功能
- C++发送邮件和附件
- Qt + CURL + mimetic 发送邮件(带附件)
- C++实现发送邮件和附件功能
- Qt + CURL + mimetic 发送邮件(带附件)
- perl模块之MIME::Lite发送有附件的邮件
- 邮件正文及其附件的发送的C++实现
- SMTP VS C++实现向多人发送邮件,可带多个附件
- C++发送邮件和附件